При работе с криптографическими хеш-функциями, такими как SHA256, часто возникает необходимость получить одинаковый результат на разных платформах. В данном случае, мы хотим, чтобы код на Delphi выдавал тот же хеш, что и аналогичный код на C# при использовании UTF-8 кодировки.
Проблема
Основная причина различий в хешах между C# и Delphi - разное кодирование входных данных. В C# по умолчанию используется UTF-8, в то время как в Delphi (при использовании стандартных функций) могут применяться другие кодировки.
Решение
Вариант 1: Использование стандартных функций Delphi (RTL)
uses
System.Hash;
function GetSHA256Hash(const Input: string): string;
var
Hash: THashSHA2;
begin
Hash := THashSHA2.Create;
try
// Используем UTF-8 кодировку
Result := Hash.GetHashString(Input, TEncoding.UTF8);
finally
Hash.Free;
end;
end;
Вариант 2: Использование библиотеки Indy
uses
IdHash, IdHashSHA, IdGlobal;
function GetSHA256HashWithIndy(const Input: string): string;
var
Hash: TIdHashSHA256;
begin
Hash := TIdHashSHA256.Create;
try
// Используем UTF-8 кодировку
Result := Hash.HashString(Input, TEncoding.UTF8);
finally
Hash.Free;
end;
end;
Вариант 3: Прямая работа с байтами
uses
System.Hash, System.Classes, System.SysUtils;
function GetSHA256HashFromBytes(const Input: string): string;
var
Bytes: TBytes;
Hash: THashSHA2;
begin
// Преобразуем строку в байты с UTF-8 кодировкой
Bytes := TEncoding.UTF8.GetBytes(Input);
// Вычисляем хеш
Hash := THashSHA2.Create;
try
Result := Hash.GetHashString(Bytes);
finally
Hash.Free;
end;
end;
Пример использования
procedure TForm1.Button1Click(Sender: TObject);
var
Input: string;
Hash: string;
begin
Input := '12345';
Hash := GetSHA256Hash(Input);
ShowMessage('SHA256 hash of "' + Input + '": ' + Hash);
end;
Сравнение с C
Для строки "12345" все три приведенных метода дадут одинаковый результат, который будет соответствовать C# версии:
Всегда явно указывайте кодировку при преобразовании строк в байты
Для совместимости с другими системами используйте UTF-8 как стандартную кодировку
Убедитесь, что вы сравниваете хеши в одном формате (обычно шестнадцатеричная строка)
Альтернативные решения
Если вам нужно работать с другими кодировками, вы можете модифицировать функции, передавая кодировку как параметр:
function GetSHA256HashEx(const Input: string; Encoding: TEncoding): string;
var
Hash: THashSHA2;
begin
Hash := THashSHA2.Create;
try
Result := Hash.GetHashString(Input, Encoding);
finally
Hash.Free;
end;
end;
Теперь вы можете получить одинаковые хеши между C# и Delphi, если будете использовать одинаковые кодировки входных данных. Это особенно важно при работе в распределенных системах, где данные обрабатываются на разных платформах.
Статья описывает способы получения идентичного SHA256 хеша строки в Delphi и C# при использовании UTF-8 кодировки.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS