-
BondFx © (22.04.16 22:24) [0]Не могу разобраться с мд5 мужики: наваял вот такой код:function md5(st: AnsiString): string;
var D: TIdBytes;
i: integer;
S: TMemoryStream;
Hash, Hash2: TIdBytes;
d5: TIdHashMessageDigest5;
st1: string;
begin
Result := '';
S:= TMemoryStream.Create;
d5:= TIdHashMessageDigest5.Create;
try
Hash:= d5.HashString(st, IndyTextEncoding(encUTF16LE));
WriteStringToStream(S, st, -1, 1, IndyTextEncoding(encUTF16LE));
Hash2:= d5.HashStream(S);
Result:= ToHex2(Hash);
Result:= ToHex2(Hash2);
finally
d5.Free;
S.Free;
end;
end;
при выполнении сравниваю хеш и хеш2 они разные для одной и той же строки. ЧЯДНТ???? -
BondFx © (22.04.16 22:28) [1]ФункцииWriteStringToStream
иToHex
выдрал из кода Инди -
Eraser © (22.04.16 23:13) [2]
> BondFx © (22.04.16 22:24)
какие-то странные манипуляции с кодировками. я бы вообще не стал там полагаться на Indy.
держи работающий вариант
class function TMyHashUtils.MD5(ASource: string): string;
var
Data: TBytes;
begin
Data := TEncoding.Unicode.GetBytes(ASource);
Result := MD5FromData(Data);
end;
class function TMyHashUtils.MD5FromData(AData: TBytes): string;
var
IdMD5: TIdHashMessageDigest;
msData: TMemoryStream;
begin
IdMD5 := TIdHashMessageDigest5.Create;
msData := TMemoryStream.Create;
try
msData.Write(AData[0], Length(AData));
msData.Position := 0;
Result := IdMD5.HashStreamAsHex(msData);
finally
msData.Free;
IdMD5.Free;
end;
end;
class function TMyHashUtils.AnsiMD5(ASource: AnsiString): AnsiString;
var
Data: TBytes;
begin
Data := TEncoding.ANSI.GetBytes(string(ASource));
Result := AnsiString(MD5FromData(Data));
end;
в новейших версиях Делфи можно обойтись вообще без Indy, там в RTL появились функции http://docwiki.embarcadero.com/Libraries/XE8/en/System.Hash.THashMD5 -
BondFx © (23.04.16 00:01) [3]Да вот именно было нужно разобраться с кодировкой на делфи 7. Перерыл все функции ХЕ, но разобрался. Не сходилось потому, что при записи в стрим и чтения не устанавливалась каретка стрима в 0. Добавил Position:=0 и данные сошлись. Для делфи 7 написал:function md5(St: String): string;
var D: array of byte;
i: integer;
S: TMemoryStream;
begin
Result := '';
S:= TMemoryStream.Create;
SetLength(D, Length(St)*2);
for i:= 0 to Length(St) - 1 do begin
D[i*2]:= Byte(St[i+1]);
D[i*2+1]:= $0;
end;
S.WriteBuffer(D[0], Length(St)*2);
S.Position:=0;
with TIdHashMessageDigest5.Create do
try
Result := UpperCase(AsHex(HashValue(s)));
finally
Free;
S.Free;
end;
end;
Теперь работает как нужно в Д7. Преобразование Ansi в Unicode сделал простым добавлением пустого байта после каждого символа в стоке. -
BondFx © (23.04.16 00:16) [4]Блин 3 часа бился из-за этого... Переработался....
-
> Преобразование Ansi в Unicode сделал простым добавлением
> пустого байта после каждого символа в стоке.
Взять WideString и присвоить одно другому не проще? (в D7) -
Но так Ansi в Unicode не преобразовывают.
-
superbot © (24.04.16 08:28) [7]Ппробуйте Библиотеку DCPCrypt http://www.cityinthesky.co.uk/wp-content/uploads/dcpdemos.zip Там все уже разжевано и даже с примерами
типа мой модуль только уже урезанный, потоки сами прикрутитеunit CryptMod;
interface
Uses
System.SysUtils, DCPMD5;
function CheckHash(hash: AnsiString; l: integer): boolean;
function DigestToTxt(Digest: Array of byte): AnsiString;
function GetMD5Hash(AStrData: AnsiString): AnsiString;
implementation
function CheckHash(hash: AnsiString; l: integer): boolean;
var sh: set of AnsiChar;
i: integer;
begin
Result := false;
sh := ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','a','b','c','d' ,'e','f'];
if Length(hash) <> l then Exit;
for i:=1 to Length(hash) do
if Not (hash[i] in sh) then Exit;
result := True;
end;
function DigestToTxt(Digest: Array of byte): AnsiString;
var i : integer;
begin
for i := 0 to Length(Digest) -1 do Result := Result + IntToHex(Digest[i], 2);
end;
function GetMD5Hash(AStrData: AnsiString): AnsiString;
var MD5: TDCP_md5;
Digest: array [0..15] of byte;
begin
try
MD5 := TDCP_md5.Create(Nil);
MD5.Init;
MD5.UpdateStr(AStrData);
MD5.Final(Digest);
Result := DigestToTxt(Digest);
finally
MD5.Free;
end;
end;
end. -
superbot © (24.04.16 08:42) [8]
> superbot © (24.04.16 08:28) [7]
CCылка на на оригинальную библиотеку адаптированную ко всем XE версиям делфи: http://www.cityinthesky.co.uk/wp-content/uploads/dcpcrypt2-2010.zip в текущий момент она стоит у меня на Embarcadero RAD Studio 10 Seattle версии.
Уже написано реально работающее приложение с использованием модуля
https://yadi.sk/i/5n_WiuWArEiu8