2010-03-22 9 views
2

J'ai utilisé la même fonction (OneWayEncrypt (edit1.Text)) dans Delphi 5 et 2010.
Pourquoi les résultats sont-ils différents? (Ou comment puis-je donner les mêmes résultats de Delphi 2010?)Delphi 5 à 2010

uses Sysutils, Windows, Dialogs, classes; 

function OneWayEncrypt(AStr: string): string; 
PROCEDURE CalcCRC32 (p: pointer; ByteCount: DWORD; VAR CRCvalue: DWORD); 

implementation 

const 
    table: ARRAY[0..255] OF DWORD = 
    (
    //table consts are here 
); 

PROCEDURE CalcCRC32(p: pointer; ByteCount: DWORD; VAR CRCvalue: DWORD); 
VAR 
    i: DWORD; 
    q: ^Byte; 
BEGIN 
    q := p; 
    FOR i := 0 TO ByteCount - 1 DO 
    BEGIN 
    CRCvalue := (CRCvalue SHR 8) XOR table[q^ XOR (CRCvalue AND $000000FF)]; 
    INC(q); 
    END 
END; 

function OneWayEncrypt(AStr: string): string; 
var 
    dwCrc: DWORD; 
    s: string; 
begin 
    dwCrc := $FFFFFFFF; 
    s := 'X' + AStr + '7F'; 
    CalcCRC32(Addr(s[1]), Length(s), dwCrc); 
    result := IntToHex(dwCrc, 8); 
end; 
+2

Comment est-ce une fonction de cryptage? C'est une fonction de hachage avec perte utilisant CRC32 pour calculer des hachages très faibles. –

+0

Points intéressants: Lorsque vous exécutez ce code, le résultat de OneWayEncrypt est-il une valeur à huit chiffres dont les quatre chiffres les plus significatifs sont tous à zéro? Parce que quand j'exécute ce code ici, en utilisant une table que j'ai faite moi-même pour vos constantes ci-dessus, qui sont de taille DWORD, pour une raison quelconque, j'obtiens ce résultat. –

Répondre

10

Savez-vous que string fait référence à une chaîne Unicode dans D2010, alors qu'elle fait référence à AnsiString dans les versions < D2009? Cela devrait être la source de votre problème.

Alors vous avez deux choix:

  • Vous pouvez remplacer toutes les apparences de string avec AnsiString. Cela devrait vous donner les mêmes résultats qu'en D5, bien sûr sans support Unicode
  • Vous pouvez refactoriser votre code. Je suppose que le pointeur - "piratage" est la partie cruciale ici. Mais je dois avouer, je n'ai pas pris le temps de bien comprendre le code ;-) (Il se pourrait très bien que votre code ne puisse pas être utilisé avec Unicode de toute façon, en raison des 255 consts = ISO8859?)
+0

Exactement. Lisez les articles "Delphi dans un monde Unicode" de Nick Hodge sur le site web EMbarcadero/Codegear Developers Network. –

4

D2010 (et D2009) utilisent des chaînes Unicode (de Widestrings), de sorte que la taille des caractères est différent (octets). Essayez de passer toutes les références de chaîne à AnsiString.

+0

Et Char à AnsiChar, et PChar à PAnsichar. Sauf qu'une recherche aveugle et le remplacement sans savoir ce que vous faites se tromperont à certains endroits (disons 10%), et bien dans d'autres (disons 90%). Vous devez donc réfléchir et apprendre, et prendre des décisions intelligentes, sans appliquer aveuglément les règles, pour les porter vers le haut. –

+0

Dans le cas de ce type, ce serait un pas en avant, et deux pas en arrière. voir ma réponse –

3

Port minimal, un changement de ligne:

// old code: 
    CalcCRC32(Addr(s[1]), Length(s), dwCrc); 

    // delphi 2010 code: 
    CalcCRC32(PAnsiChar(AnsiString(s)), Length(s), dwCrc); 

S'il vous plaît être conscient que tout contenu unicode dans le unicode "String" sera perdu, mais tout ANSI (AZ, 1,3,4, vous savez) les points de code que vous utilisiez auparavant, par exemple "Hello", devraient fonctionner comme avant. Comme il s'agit d'un algorithme CRC32, il pourrait facilement faire un CRC32 sur un encodage UTF8 de la chaîne.