DCPcrypt Хеширование Немецких Umlauts
Я использую DCPcrypt и SHA512 для хэш-строк.
Я использую версию Уоррена Постмы https://bitbucket.org/wpostma/dcpcrypt2010
Он работает нормально. Однако он опоздает с как немецкие умляуты ä, ö, ü и, вероятно, других юникоды.
Я использую библиотеку следующим образом:
function TForm1.genhash(str: string): string;
var
Hash : TDCP_sha512;
Digest: array[0..63] of byte;
i: integer;
s: string;
begin
s:= '';
hash := TDCP_sha512.Create(nil);
if hash<>nil then
begin
try
Hash.Init;
Hash.UpdateStr(str);
Hash.Final(Digest);
for i:= 0 to length(Digest)-1 do
s:= s + IntToHex(Digest[i],2);
finally
hash.free;
end;
end;
Result := s;
end;
когда я ввожу букву ä
Я ожидаю, что выход должен быть:
64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157
Я проверил его на этих сайтах: http://hashgenerator.de/ http://passwordsgenerator.net/sha512-hash-generator/
Я:1A7F725BD18E062020A646D4639F264891368863160A74DF2BFC069C4DADE04E6FA854A2474166EED0914B922A9D8BE0C89858D437DDD7FBCA5C9C89FC07323A
Итак, мой вопрос: Как я могу использовать библиотеку DCPcrypt для создания хэшей для немецких umlauts? Спасибо
1 ответов
это самая распространенная ошибка, которую люди делают с хэширования и шифрования. Эти algos работают на двоичных данных, но вы передаете текст. Что-то где-то должно кодировать этот текст как двоичный. И какую кодировку следует использовать. Откуда вы знаете, что ваша библиотека использует то же самое, что и онлайн-инструмент? Вы не.
Итак, вот правило для вас, чтобы следовать. Никогда не хэшировать текст. Просто не делай этого. Кодируйте текст как двоичный, используя четко определенный, явно выбранный кодирование. И хэша. Я предлагаю вам кодировать как UTF-8 и хэшировать это. Итак,TEncoding.UTF8.GetBytes(...)
- твой друг.
теперь, глядя на фактическую деталь здесь, вы вызываете этот метод:
procedure UpdateStr(const Str: RawByteString);
на RawByteString
параметр, означает, что ваш текст Unicode преобразуется в строку ANSI с системной кодовой страницей по умолчанию. Я уверена, что ты не этого хочешь. Действительно, компилятор говорит следующее:
[предупреждение dcc32] W1058 неявное приведение строк с потенциальной потерей данных из 'string ' в'RawByteString'
поэтому компилятор говорит вам, что вы делаете что-то неправильно. Вы действительно должны внимательно следить за сообщениями компилятора.
теперь вы можете позвонить UpdateUnicodeStr
вместо UpdateStr
. Но опять же, откуда вы знаете, какая кодировка используется? Это внутренняя кодировка UTF-16LE.
но, давайте следовать моему правилу не кодирование текст.
{$APPTYPE CONSOLE}
uses
SysUtils, Classes, DCPsha512;
function genhash(str: string): string;
var
Bytes: TBytes;
Hash: TDCP_sha512;
Digest: array[0..63] of byte;
begin
Bytes := TEncoding.UTF8.GetBytes(str); // encode text as UTF-8 bytes
hash := TDCP_sha512.Create(nil);
try
Hash.Init;
Hash.Update(Pointer(Bytes)^, Length(Bytes));
Hash.Final(Digest);
finally
hash.Free;
end;
// convert the digest to a hex hash string
SetLength(Result, Length(Digest)*2);
BinToHex(Digest, PChar(Result), Length(Digest));
end;
begin
Writeln(genhash('ä'));
Readln;
end.
выход
64868C5784A6004E675BCF405F549369BF607CD3269C0CAC1711E21BA9F40A5ABBF0C7535856E7CF77EA55A072DD04AA89EEA361E95F497AA965309B50587157
обратите внимание, что я упростил код другими способами. Я удалил локальную строковую переменную и работал непосредственно с Result
. Я использовал BinToHex
С Classes
единица для преобразования digest в hex. Я также изменил это код:
hash := TDCP_sha512.Create(nil);
if hash<>nil then
....
удалить if
заявление, которое не требуется. При сбое конструктора возникает исключение.
пожалуйста, следуйте моему правилу никогда не хэшировать текст. Это сослужит вам хорошую службу!