2010-03-22 5 views
2

Я использовал ту же функцию (OneWayEncrypt (Edit1.Text)) в Delphi 5 и 2010
Почему результаты отличаются? (Или как я могу дать те же результаты 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

Как это функция шифрования? Это функция хэширования с потерями, использующая CRC32 для вычисления очень слабых хэшей. –

+0

Интересные моменты: когда вы запускаете этот код, является ли результат OneWayEncrypt восьмизначным значением, причем самые значащие четыре цифры равны нулю? Потому что, когда я запускаю этот код здесь, используя некоторую таблицу, которую я составил для себя для ваших констант выше, размер DWORD по какой-то причине, я получаю этот результат. –

ответ

10

Знаете ли вы, что string относится к строке Unicode в D2010, а относится к AnsiString в версиях < D2009? Это должно быть источником вашей проблемы.

Так у вас есть два варианта:

  • Вы можете заменить все выступления string с AnsiString. Это должно дать вам те же результаты, что и в D5, конечно, без поддержки Unicode.
  • Вы можете реорганизовать свой код. Я предполагаю, что указатель - «взлом» - вот важная часть здесь. Но я должен признать, что я не нашел времени, чтобы полностью понять код ;-) (Вполне возможно, что ваш код не может использоваться с Unicode в любом случае из-за 255 consts = ISO8859?)
+0

Точно. Прочитайте статьи Ника Ходжа «Дельфы в мире Юникода» на веб-сайте Developers Network компании EMbarcadero/Codegear. –

4

D2010 (D2009 и) использовать Unicode строк (widestrings), поэтому размер символов отличается (в байтах). Попробуйте переключить все ссылки на строку в AnsiString.

+0

И Char для AnsiChar, и PChar для PAnsichar. За исключением того, что слепой поиск и замена, не зная, что вы делаете, будут ошибочными в некоторых местах (скажем, 10%), а прямо в других (скажем, 90%). Таким образом, вы должны сделать некоторые мысли, и учиться, и принимать разумные решения, а не слепо применять правила, чтобы порт вверх. –

+0

В этом случае, это будет один шаг вперед и два шага назад. см. мой ответ –

3

Минимальный порт, один линии изменения:

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

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

Пожалуйста, обратите внимание, что любое содержимое юникода в юникод «строка» будет потеряна, но любой ANSI (AZ, 1,3,4, вы знаете,), которые вы использовали раньше, например «Привет», должны работать так же, как и раньше. Поскольку это алгоритм CRC32, он также может легко сделать CRC32 в кодировке UTF8 строки.

Смежные вопросы