Em C#, temos esta função:
public string GetStringSha256Hash(string text, Encoding coding)
{
string result = "";
if (text != null)
{
using (SHA256 sHA256Managed = SHA256.Create())
{
byte[] bytes = coding.GetBytes(text);
byte[] array = sHA256Managed.ComputeHash(bytes);
result = BitConverter.ToString(array).Replace("-", string.Empty);
}
}
return result;
}
Estou tentando fazer o mesmo no Delphi, mas continuo obtendo resultados diferentes.
Algo tão simples como isto:
Result := THashSHA2.GetHashString(Text);
retorna um resultado diferente.
Suspeito que seja porque em C# sempre usamos UTF-8, mas não consigo descobrir como usar codificação em Delphi.
Eu tentei isso:
var
Hash: TIdHashSHA256;
begin
Hash := TIdHashSHA256.Create;
try
SHA256Hash := Hash.HashString(Text, TEncoding.UTF8);
mas dá erro de compilação
[Erro dcc32] Unit1.pas(216): E2010 Tipos incompatíveis: 'IIdTextEncoding' e 'TEncoding'
Qual é a maneira correta de fazer isso no Delphi?
O valor 12345
retorna 1445217533E7D4D0CFFD9109C4EDB60D62A02C0F0DE9537BE44F5E00D348EB4F
em C#, mas 5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5
em Delphi.
Quero que a versão Delphi retorne o mesmo valor que a versão C#.
Hashes são calculados em bytes, não em caracteres de texto. Qualquer código que você usar para fazer hash de uma string precisará codificar os caracteres em bytes antes de calcular o hash nos bytes. Ao fazer hash de strings em sistemas diferentes, você precisa ter certeza de que elas estão usando a mesma codificação de bytes.
O código C# está codificando a entrada
string
para um array de bytes viacoding.GetBytes(text)
. Você não indicou qualEncoding
está sendo passado paraGetStringSha256Hash()
, mas o resultado do hash C# que você mostrou é o que você obtém ao fazer o hash de uma string usando UTF-16LE (ou seja,Encoding.Unicode
).Ao usar a classe Delphi RTL
THashSHA2
, ela não permite que você especifique uma codificação de bytes ao fazer hash de umstring
. OGetHashString()
método que recebe astring
é codificado para usarTEncoding.UTF8
. Isso é consistente com o resultado do hash Delphi que você mostrou. Para usar uma codificação de bytes diferente, as opções alternativas são:use a
THashSHA2.GetHashString()
sobrecarga que recebe umTStream
, e então você pode passar um fluxo contendo bytes codificados em UTF-16LE, por exemplo:use o
THashSHA2.Update()
método, passando-lhe uma matriz de bytes codificada em UTF-16, por exemplo:Ao usar a classe do Indy
TIdHashSHA256
, o erro do compilador é causado pelo fato de que o Indy não usa aTEncoding
classe 1 do Delphi RTL , mas sim sua própriaIIdTextEncoding
interface (porque o Indy ainda suporta versões pré-Unicode do Delphi que não têm aSysUtils.TEncoding
classe disponível), por exemplo:1 : Se você quiser usar um
SysUtils.TEncoding
com Indy, você pode envolvê-lo em umIIdTextEncoding
usando aIndyTextEncoding()
função naIdGlobal
unidade, por exemplo: