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 заявление, которое не требуется. При сбое конструктора возникает исключение.

пожалуйста, следуйте моему правилу никогда не хэшировать текст. Это сослужит вам хорошую службу!