• 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 часа бился из-за этого... Переработался....
  • DVM © (23.04.16 18:08) [5]

    > Преобразование Ansi в Unicode сделал простым добавлением
    > пустого байта после каждого символа в стоке.

    Взять WideString и присвоить одно другому не проще? (в D7)
  • DVM © (23.04.16 18:10) [6]
    Но так 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
Есть новые Нет новых   [134435   +33][b:0][p:0.002]