AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

MD5 Implementation für Delphi 2009

Ein Thema von wth · begonnen am 22. Sep 2008 · letzter Beitrag vom 20. Okt 2008
Antwort Antwort
Seite 1 von 2  1 2      
wth

Registriert seit: 17. Sep 2008
43 Beiträge
 
RAD-Studio 2009 Arc
 
#1

MD5 Implementation für Delphi 2009

  Alt 22. Sep 2008, 18:20
Hi,

Hat bzw. kennt jemand eine funktionierende MD5 Implementation für Delphi 2009.
Alles was ich bisher gefunden habe, funktioniert mit Delphi 2009 nicht mehr, auch nicht, wenn ich im Source alle Strings in AnsiStrings umwandle.

Was muss man bei diesem Code z.B ändern, damit er mit Delphi 2009 funktioniert?

Danke!
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#2

Re: MD5 Implementation für Delphi 2009

  Alt 22. Sep 2008, 19:43
Ich weiß zwar nicht, was für Schweinerein in D2009 eingebaut sind, aber meine CRC/Hash-Routinen laufen bis D2006/7 und Lazarus/FPC2.2.2 sogar unter Linux/ARM (in der PurPascal-Version).

Ich sehe also kein Problem für D2009 bzw. wäre interessiert an Hinweisen, falls es doch welche geben sollte.

Gruß Gammatester
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.442 Beiträge
 
Delphi 12 Athens
 
#3

Re: MD5 Implementation für Delphi 2009

  Alt 22. Sep 2008, 20:44
Zitat von gammatester:
Ich weiß zwar nicht, was für Schweinerein in D2009 eingebaut sind, aber meine CRC/Hash-Routinen laufen bis D2006/7 und Lazarus/FPC2.2.2 sogar unter Linux/ARM (in der PurPascal-Version).

Ich sehe also kein Problem für D2009 bzw. wäre interessiert an Hinweisen, falls es doch welche geben sollte.

Gruß Gammatester
Überprüfe mal alle Stellen, an denen du davon ausgehst, daß Sizeof(char) = 1 ist bzw. daß die Anzahl der Zeichen eines Strings gleich der Speichergröße dieses Strings ist.

Beispiel: MD5.pas - MD5SelfTest - SingleTest

Delphi-Quellcode:
  
  function SingleTest(s: string; TDig: TMD5Digest): boolean;
    {-do a single test, const not allowed for VER<7}
    { Two sub tests: 1. whole string, 2. one update per char}
  var
    i: integer;
  begin
    SingleTest := false;
    {1. Hash complete string}
    MD5Full(Digest, @s[1],length(s));
    {Compare with known value}
    if not HashSameDigest(@MD5_Desc, PHashDigest(@Digest), PHashDigest(@TDig)) then exit;
    {2. one update call for all chars}
    MD5Init(Context);
    for i:=1 to length(s) do MD5Update(Context,@s[i],1);
    MD5Final(Context,Digest);
    {Compare with known value}
    if not HashSameDigest(@MD5_Desc, PHashDigest(@Digest), PHashDigest(@TDig)) then exit;
    SingleTest := true;
  end;
Der Aufruf von MD5Full wird unter D2009 etwas anders ausgehen, als noch unter D2007. Eine Lösung, die in beiden Fällen läuft wäre

MD5Full(Digest, @s[1], length(s)*sizeof(Char)); Allerdings glaube ich kaum, daß die Hashwerte eines AnsiStrings mit denen eines UnicodeStrings übereinstimmen, welbst wenn sie die gleiche Zeichenfolge enthalten.
Uwe Raabe
  Mit Zitat antworten Zitat
gammatester

Registriert seit: 6. Dez 2005
999 Beiträge
 
#4

Re: MD5 Implementation für Delphi 2009

  Alt 22. Sep 2008, 21:03
Zitat von Uwe Raabe:
Überprüfe mal alle Stellen, an denen du davon ausgehst, daß Sizeof(char) = 1 ist bzw. daß die Anzahl der Zeichen eines Strings gleich der Speichergröße dieses Strings ist.

Beispiel: MD5.pas - MD5SelfTest - SingleTest
Hallo Uwe,

vielen Dank für die Hinweise. Ich hatte mich zwar bemüht, möglichst keine 'nackten' strings zu benutzen, aber bei den Selbstests sind also noch welche.

Ich denke, ich werde bei den nächsten Updates dort statt string zB einen Typ str128 = string[128] benutzen, oder geht die Quälerei soweit daß ein Zeichen eines str128 mehr als ein Byte haben kann?

Gruß Gammatester
  Mit Zitat antworten Zitat
wth

Registriert seit: 17. Sep 2008
43 Beiträge
 
RAD-Studio 2009 Arc
 
#5

Re: MD5 Implementation für Delphi 2009

  Alt 22. Sep 2008, 21:10
OK, Danke, ich denke mal, dass ich es damit hinbekomme, ansonsten melde ich mich hier wieder.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.442 Beiträge
 
Delphi 12 Athens
 
#6

Re: MD5 Implementation für Delphi 2009

  Alt 22. Sep 2008, 21:12
Zitat von gammatester:
Ich denke, ich werde bei den nächsten Updates dort statt string zB einen Typ str128 = string[128] benutzen, oder geht die Quälerei soweit daß ein Zeichen eines str128 mehr als ein Byte haben kann?
Nein, ShortStrings sind so geblieben. Damit brauchst du auch die Testergebnisse nicht neu ermitteln...
Uwe Raabe
  Mit Zitat antworten Zitat
Benutzerbild von hitzi
hitzi

Registriert seit: 2. Jan 2003
Ort: Eibau
768 Beiträge
 
Delphi 2010 Professional
 
#7

Re: MD5 Implementation für Delphi 2009

  Alt 20. Okt 2008, 14:08
Hallo,

ich reihe mich mal hier mit ein.
Unter Delphi 2009 und den Units von Gammatester bekomme ich nicht den richtigen CRC.

Hier ist mein Beispielprogramm:
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, md5, hash, mem_util;

type
  TForm1 = class(TForm)
    edt1: TEdit;
    btn1: TButton;
    edt2: TEdit;
    procedure btn1Click(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function HexString(const x: array of byte): string;
  {-HEX string from memory}
begin
  Result := HexStr(@x, sizeof(x));
end;

procedure TForm1.btn1Click(Sender: TObject);
var MD5Context : TMD5Digest;
begin
  MD5Full(MD5Context, @edt1.Text[1], length(edt1.Text) * SizeOf(Char));
  edt2.Text := HexString(MD5Context);
end;

end.
Beispieltext ist
Zitat:
Thomas
Vergleichsresultat von http://www.hashgenerator.de/: ef6e65efc188e7dffd7335b646a85a21
Das falsche Resultat von meinem Testprogramm: e7153adbc66d908704b472c4d58e96d3

Liegt garantiert an der Unicode Geschichte. Wie kann ich nun unter Delphi 2009 einen MD5 Hash aus einem String errechnen lassen?

Viele Grüße
Thomas
Besucht doch mal http://www.hitziger.net
  Mit Zitat antworten Zitat
Gerome

Registriert seit: 4. Sep 2002
Ort: Server-Raum im Keller
316 Beiträge
 
#8

Re: MD5 Implementation für Delphi 2009

  Alt 20. Okt 2008, 14:25
Zitat von hitzi:
Liegt garantiert an der Unicode Geschichte. Wie kann ich nun unter Delphi 2009 einen MD5 Hash aus einem String errechnen lassen?
Sagt mal ... wie arbeitet denn MD5? Wenn - falls - ich richtig liege, dann betrachtet doch MD5 die Daten als Byte-Strom. Dass diese Bytes u.U. von uns zusammenhängend als MD5 betrachtet werden, ist doch dem MD5 egal, oder? Anbei ein Screenshot mit Speicherauszug. Da ist zu sehen, dass der String "Thomas" bei den neuen Unicode-Strings (wenig überraschend) breiter im Speicher liegt als mit den Ansi-Strings. Aus diesem Grund denke ich, dass ein Vergleich mit einem MD5-Rechner auf einer Webseite insofern nicht gültig ist, da man der Webseite - zumindest der im gegebenen Beispiel - wirklich nur die Bytes übergibt, die den String "Thomas" ausmachen.
Miniaturansicht angehängter Grafiken
md5_844.jpg  
Es lebe der eigene Keller.
  Mit Zitat antworten Zitat
Benutzerbild von hitzi
hitzi

Registriert seit: 2. Jan 2003
Ort: Eibau
768 Beiträge
 
Delphi 2010 Professional
 
#9

Re: MD5 Implementation für Delphi 2009

  Alt 20. Okt 2008, 14:34
Hmmm ... also kann ich dann davon ausgehen, dass zum Beispiel die bei PHP vorhanden md5() Funktion nur auf Basis von Ansistrings arbeitet, da ja dort auch nur der angezeigte Text durch diese Funktion gejagt wird?

Wenn's nur mit Ansistrings funktioniert dann funktioniert die MD5 Funktion von hier(http://forum.vingrad.ru/forum/topic-230076.html):
Delphi-Quellcode:
function md5(s : AnsiString) : AnsiString;
var a : array[0..15] of byte;
    i : integer;
    LenHi, LenLo : longword;
    Index : DWord;
    HashBuffer : array[0..63] of byte;
    CurrentHash : array[0..3] of DWord;

  procedure Burn;
  begin
    LenHi := 0;
    LenLo := 0;
    Index := 0;
    FillChar(HashBuffer, Sizeof(HashBuffer), 0);
    FillChar(CurrentHash, Sizeof(CurrentHash), 0);
  end;

  procedure Init;
  begin
    Burn;
    CurrentHash[0] := $67452301;
    CurrentHash[1] := $efcdab89;
    CurrentHash[2] := $98badcfe;
    CurrentHash[3] := $10325476;
  end;

  function LRot32(a, b : longword) : longword;
  begin
    Result:= (a shl b) or (a shr (32 - b));
  end;

  procedure Compress;
  var Data : array[0..15] of dword;
      A, B, C, D : dword;
  begin
    Move(HashBuffer, Data, Sizeof(Data));
    A := CurrentHash[0];
    B := CurrentHash[1];
    C := CurrentHash[2];
    D := CurrentHash[3];
    A := B + LRot32(A + (D xor (B and (C xor D))) + Data[ 0] + $d76aa478,7);
    D := A + LRot32(D + (C xor (A and (B xor C))) + Data[ 1] + $e8c7b756,12);
    C := D + LRot32(C + (B xor (D and (A xor B))) + Data[ 2] + $242070db,17);
    B := C + LRot32(B + (A xor (C and (D xor A))) + Data[ 3] + $c1bdceee,22);
    A := B + LRot32(A + (D xor (B and (C xor D))) + Data[ 4] + $f57c0faf,7);
    D := A + LRot32(D + (C xor (A and (B xor C))) + Data[ 5] + $4787c62a,12);
    C := D + LRot32(C + (B xor (D and (A xor B))) + Data[ 6] + $a8304613,17);
    B := C + LRot32(B + (A xor (C and (D xor A))) + Data[ 7] + $fd469501,22);
    A := B + LRot32(A + (D xor (B and (C xor D))) + Data[ 8] + $698098d8,7);
    D := A + LRot32(D + (C xor (A and (B xor C))) + Data[ 9] + $8b44f7af,12);
    C := D + LRot32(C + (B xor (D and (A xor B))) + Data[10] + $ffff5bb1,17);
    B := C + LRot32(B + (A xor (C and (D xor A))) + Data[11] + $895cd7be,22);
    A := B + LRot32(A + (D xor (B and (C xor D))) + Data[12] + $6b901122,7);
    D := A + LRot32(D + (C xor (A and (B xor C))) + Data[13] + $fd987193,12);
    C := D + LRot32(C + (B xor (D and (A xor B))) + Data[14] + $a679438e,17);
    B := C + LRot32(B + (A xor (C and (D xor A))) + Data[15] + $49b40821,22);
    A := B + LRot32(A + (C xor (D and (B xor C))) + Data[ 1] + $f61e2562,5);
    D := A + LRot32(D + (B xor (C and (A xor B))) + Data[ 6] + $c040b340,9);
    C := D + LRot32(C + (A xor (B and (D xor A))) + Data[11] + $265e5a51,14);
    B := C + LRot32(B + (D xor (A and (C xor D))) + Data[ 0] + $e9b6c7aa,20);
    A := B + LRot32(A + (C xor (D and (B xor C))) + Data[ 5] + $d62f105d,5);
    D := A + LRot32(D + (B xor (C and (A xor B))) + Data[10] + $02441453,9);
    C := D + LRot32(C + (A xor (B and (D xor A))) + Data[15] + $d8a1e681,14);
    B := C + LRot32(B + (D xor (A and (C xor D))) + Data[ 4] + $e7d3fbc8,20);
    A := B + LRot32(A + (C xor (D and (B xor C))) + Data[ 9] + $21e1cde6,5);
    D := A + LRot32(D + (B xor (C and (A xor B))) + Data[14] + $c33707d6,9);
    C := D + LRot32(C + (A xor (B and (D xor A))) + Data[ 3] + $f4d50d87,14);
    B := C + LRot32(B + (D xor (A and (C xor D))) + Data[ 8] + $455a14ed,20);
    A := B + LRot32(A + (C xor (D and (B xor C))) + Data[13] + $a9e3e905,5);
    D := A + LRot32(D + (B xor (C and (A xor B))) + Data[ 2] + $fcefa3f8,9);
    C := D + LRot32(C + (A xor (B and (D xor A))) + Data[ 7] + $676f02d9,14);
    B := C + LRot32(B + (D xor (A and (C xor D))) + Data[12] + $8d2a4c8a,20);
    A := B + LRot32(A + (B xor C xor D) + Data[ 5] + $fffa3942,4);
    D := A + LRot32(D + (A xor B xor C) + Data[ 8] + $8771f681,11);
    C := D + LRot32(C + (D xor A xor B) + Data[11] + $6d9d6122,16);
    B := C + LRot32(B + (C xor D xor A) + Data[14] + $fde5380c,23);
    A := B + LRot32(A + (B xor C xor D) + Data[ 1] + $a4beea44,4);
    D := A + LRot32(D + (A xor B xor C) + Data[ 4] + $4bdecfa9,11);
    C := D + LRot32(C + (D xor A xor B) + Data[ 7] + $f6bb4b60,16);
    B := C + LRot32(B + (C xor D xor A) + Data[10] + $bebfbc70,23);
    A := B + LRot32(A + (B xor C xor D) + Data[13] + $289b7ec6,4);
    D := A + LRot32(D + (A xor B xor C) + Data[ 0] + $eaa127fa,11);
    C := D + LRot32(C + (D xor A xor B) + Data[ 3] + $d4ef3085,16);
    B := C + LRot32(B + (C xor D xor A) + Data[ 6] + $04881d05,23);
    A := B + LRot32(A + (B xor C xor D) + Data[ 9] + $d9d4d039,4);
    D := A + LRot32(D + (A xor B xor C) + Data[12] + $e6db99e5,11);
    C := D + LRot32(C + (D xor A xor B) + Data[15] + $1fa27cf8,16);
    B := C + LRot32(B + (C xor D xor A) + Data[ 2] + $c4ac5665,23);
    A := B + LRot32(A + (C xor (B or (not D))) + Data[ 0] + $f4292244,6);
    D := A + LRot32(D + (B xor (A or (not C))) + Data[ 7] + $432aff97,10);
    C := D + LRot32(C + (A xor (D or (not B))) + Data[14] + $ab9423a7,15);
    B := C + LRot32(B + (D xor (C or (not A))) + Data[ 5] + $fc93a039,21);
    A := B + LRot32(A + (C xor (B or (not D))) + Data[12] + $655b59c3,6);
    D := A + LRot32(D + (B xor (A or (not C))) + Data[ 3] + $8f0ccc92,10);
    C := D + LRot32(C + (A xor (D or (not B))) + Data[10] + $ffeff47d,15);
    B := C + LRot32(B + (D xor (C or (not A))) + Data[ 1] + $85845dd1,21);
    A := B + LRot32(A + (C xor (B or (not D))) + Data[ 8] + $6fa87e4f,6);
    D := A + LRot32(D + (B xor (A or (not C))) + Data[15] + $fe2ce6e0,10);
    C := D + LRot32(C + (A xor (D or (not B))) + Data[ 6] + $a3014314,15);
    B := C + LRot32(B + (D xor (C or (not A))) + Data[13] + $4e0811a1,21);
    A := B + LRot32(A + (C xor (B or (not D))) + Data[ 4] + $f7537e82,6);
    D := A + LRot32(D + (B xor (A or (not C))) + Data[11] + $bd3af235,10);
    C := D + LRot32(C + (A xor (D or (not B))) + Data[ 2] + $2ad7d2bb,15);
    B := C + LRot32(B + (D xor (C or (not A))) + Data[ 9] + $eb86d391,21);
    Inc(CurrentHash[0], A);
    Inc(CurrentHash[1], B);
    Inc(CurrentHash[2], C);
    Inc(CurrentHash[3], D);
    Index := 0;
    FillChar(HashBuffer, Sizeof(HashBuffer), 0);
  end;

  procedure Update(const Buffer; Size : longword);
  var PBuf : ^byte;
  begin
    Inc(LenHi, Size shr 29);
    Inc(LenLo, Size*8);
    if LenLo < (Size*8) then Inc(LenHi);
    PBuf := @Buffer;
    while Size > 0 do begin
      if (Sizeof(HashBuffer) - Index) <= DWord(Size) then begin
        Move(PBuf^, HashBuffer[Index], Sizeof(HashBuffer) - Index);
        Dec(Size, Sizeof(HashBuffer) - Index);
        Inc(PBuf, Sizeof(HashBuffer) - Index);
        Compress;
      end else begin
        Move(PBuf^, HashBuffer[Index], Size);
        Inc(Index, Size);
        Size := 0;
      end;
    end;
  end;

  procedure Final(var Digest);
  begin
    HashBuffer[Index] := $80;
    if Index >= 56 then Compress;
    PDWord(@HashBuffer[56])^ := LenLo;
    PDWord(@HashBuffer[60])^ := LenHi;
    Compress;
    Move(CurrentHash, Digest, Sizeof(CurrentHash));
    Burn;
  end;

begin
  Init;
  Update(s[1], Length(s));
  Final(a);
  Result := '';
  for i := 0 to 15 do Result := Result + AnsiLowerCase(IntToHex(a[i], 2));
  Burn;
end;
Thomas
Besucht doch mal http://www.hitziger.net
  Mit Zitat antworten Zitat
Daniel
(Co-Admin)

Registriert seit: 30. Mai 2002
Ort: Hamburg
13.920 Beiträge
 
Delphi 10.4 Sydney
 
#10

Re: MD5 Implementation für Delphi 2009

  Alt 20. Okt 2008, 14:48
Zitat von hitzi:
Hmmm ... also kann ich dann davon ausgehen, dass zum Beispiel die bei PHP vorhanden md5() Funktion nur auf Basis von Ansistrings arbeitet, da ja dort auch nur der angezeigte Text durch diese Funktion gejagt wird?
Nicht zwingend. Man kann gesamte Webseiten auch auf Unicode umstellen und dann ist diese Codierung auch in den Datenströmen "POST" und "GET" enthalten. Ich habe eben nachgesehen: MD5 interessiert sich tatsächlich nur für Byte-Sequenzen. Und die sind eben bei Unicode- und Ansi-Strings unterschiedlich.
Daniel R. Wolf
mit Grüßen aus Hamburg
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:00 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz