Delphi-PRAXiS
Seite 3 von 12     123 45     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   DEC 5.2 String hashen? (https://www.delphipraxis.net/192579-dec-5-2-string-hashen.html)

nahpets 2. Mai 2017 15:15

AW: DEC 5.2 String hashen?
 
Ein Hash ist doch keine Zeichenfolge. Wenn das hier nicht angezeigt werden kann, ist das vollkommen normal.

Ein MD5-Hash ist ein 16 Byte großer Binärwert. Jedes dieser 16 Bytes kann einen Wert von 0 bis 255 annehmen. Die "anzeigbaren Zeichen" sind nur 'ne Teilmenge davon.

Wenn Du den Hash unbedingt anzeigen willst, dann wandle doch diesen Wert in 'ne Zeichenfolge um.

a.def 2. Mai 2017 15:22

AW: DEC 5.2 String hashen?
 
Mein Problem besteht darin, dass ich ja weg von den Strings will in TBytes. Aber ich weiß nicht wie man
a) einen String in TBytes speichert
und
b) diese TBytes dann korrekt über einen Stream abspeichert

Michael II 2. Mai 2017 15:27

AW: DEC 5.2 String hashen?
 
Zitat:

Heißt also je genauer, desto weniger Kollisionen UND desto eher ändert sich der Hash bei Änderungen des Inputs?
Beispiel: 1Bit Hash
Wenn deine Wertemenge 2 Elemente enthält, dann werden alle Elemente deiner Definitionsmenge auf 0 oder 1 abgebildet. Du kannst also deine Definitionsmenge in "zwei Pakete" unterteilen. Wie du die Unterteilung (d.h. deine Hash Funktion) definierst ist abgängig davon, was deine Hash Funktion tun soll.

Beispiel: Wenn h alle Zeichenketten mit dem Wort Delphi erkennen soll, dann reicht eine 1Bit Funktion vollauf. Jeder Zeichenkette, welche Delphi enthält ordnet h die 1 zu, jeder anderen Kette 0 (oder umgekehrt).
Wenn wir davon ausgehen, dass du deiner Funktion h alle Texte dieser Welt füttern willst, dann enthalten die meisten Texte das Wort Delphi nicht. Deine Funktion ist aber für deinen Zweck absolut genau: Du erkennst alle Texte mit dem Wort Delphi.
Du nimmst ohne Einschränkung in Kauf, dass viel mehr Elemente auf 0 als auf die 1 abgebildet werden. D.h. du hast, wenn du zwei zufällige Texte nimmst mit sehr grosser Wahrscheinlichkeit (ungefähr 1) eine Kollision zu erwarten.

Bei anderen Aufgaben bist du eher daran interessiert, die Kollisionswahrscheinlichkeit zu minimieren. (Sortieren, Komprimieren)


Grössere Wertemenge
Wenn du die Wertemenge grösser wählst, dann kannst du natürlich die Definitionsmenge in mehr Pakete unterteilen.

Beispiel:
Eine Hash Funktion h mit einer Wertemenge mit n Elementen erlaubt es dir, deine Definitionsmenge in n Pakte zu untereilen. Je grösser du deine Wertemenge wählst, desto mehr Pakete schnürst du.

Beispiel:
In 32Bits kannst du 2^32 Werte speichern und damit deine Definitionsmenge in 2^32 Pakete unterteilen.


Deine Hash Funktion soll deiner EXE einen Wert zuordnen.

Du musst also eine Hash Funktion wählen
- mit möglichst grosser Wertemenge
- (dieser Teil ist schwierig, wenn du's selbst tun willst), welche EXEs mit ähnlicher Zeichenkette (du bist ja interessiert an Änderungen deines Programms) auf voneinander verschiedene Werte abbildet. [Es kann dir egal sein, ob Word und dein Programm durch h im gleichen Topf landen.]

Es ist eine Riesenaufgabe, solche Hash Funktionen zu definieren. Nimm besser eine erprobte mit grosser Wertemenge.

a.def 2. Mai 2017 15:48

AW: DEC 5.2 String hashen?
 
Jetzt noch einmal für ganz dumme (für mich).
ich lade eine Datei in einen Stream und den Inhalt ändere ich in MD5 oder sonst was.

Delphi-Quellcode:
aFileStream.Position := 0;
SetLength(Bytes, aFileStream.Size);
aFileStream.Read(Bytes[0], Length(Bytes));

Bytes := System.hash.THashMD5.GetHashBytes(TEncoding.ANSI.GetString(Bytes));

aFileStream.Position := aFileStream.Size;
aFileStream.Write(Bytes[0], Length(Bytes));
Wenn ich mir
Delphi-Quellcode:
TEncoding.ANSI.GetString(Bytes)
über Showmessage anzeigen lasse, sehe ich den Dateiinhalt korrekt dargestellt.
Schreibe ich Bytes dann mit Write in den Stream/die Datei, kommt nur Salat in der Datei an.

Bitte sagt mir, dass ich mich auf dem richtigen Weg befinde :pale:

Oder ist das eher so vorgesehen?
Delphi-Quellcode:
aFileStream.Position := 0;
SetLength(Bytes, aFileStream.Size);
aFileStream.Read(Bytes[0], Length(Bytes));

s := System.hash.THashMD5.GetHashString(TEncoding.ANSI.GetString(Bytes));

aFileStream.Position := aFileStream.Size;
aFileStream.Write(s[1], Length(s) * SizeOf(Byte));

p80286 2. Mai 2017 15:49

AW: DEC 5.2 String hashen?
 
Zitat:

Zitat von a.def (Beitrag 1369868)
Mein Problem besteht darin, dass ich ja weg von den Strings will in TBytes. Aber ich weiß nicht wie man
a) einen String in TBytes speichert
und
b) diese TBytes dann korrekt über einen Stream abspeichert

??
Meine naheliegende Lösung wäre
Delphi-Quellcode:
mystream.write(MyString[1],length(mystring)*sizeof(char));
nichts mit TBytes etc. Wenn der String schon vorliegt.
Ansonsten eben ein Array mit TBytes definieren und dann
Delphi-Quellcode:
mystream.write(MyBytes[0],length(myBytes));
Gruß
K-H

Edith:
Delphi-Quellcode:
Bytes := System.hash.THashMD5.GetHashBytes([B]TEncoding.ANSI.GetString[/B](Bytes));
Wofür soll das gut sein?
Wenn du einen Hash erstellst, dann ist das eine "aufgeblasene Quersumme" egal ob Du Goethes Faust oder die Bibel oder die Geschichte der 0 oder meine Kontostände hineingibst, es kommt immer 4711,42 oder 007 heraus.
der Hash von "Faust" ist nicht "Gretchen"!!
(gut kann passieren aber ist unwahrscheinlich)
pps
und für Quersummen benötigt man numerische Werte, keine Zeichen!

Michael II 2. Mai 2017 15:50

AW: DEC 5.2 String hashen?
 
Zitat:

Mein Problem besteht darin, dass ich ja weg von den Strings will in TBytes. Aber ich weiß nicht wie man
a) einen String in TBytes speichert
und
b) diese TBytes dann korrekt über einen Stream abspeichert
Wenn du deine Daten in einem Stream benötigst, dann lade doch dein File direkt dort rein.
Sowohl TMemoryStream wie TFileStream kennen eine Methode LoadFromFile.

nahpets 2. Mai 2017 16:08

AW: DEC 5.2 String hashen?
 
Im Showmessage zeigst Du aber nicht die Binärweert des Hashes an, sondern seine Übersetzung in eine anzeigbare Form.
Und wenn Du die in der DAtei haben willst, dann musst Du auch die in die Datei schreiben.

Hast Du sowas wie TotalCommander?

Dann nimm den mal. Gehe zur Datei mit dem Hash.
Taste F3 zur Anzeige.
Taste 3 zur Hexadezimalanzeige.
Taste Ende, um ans Ende der Datei zu gehen.

Dort siehst Du dann rechts den Binärwert byteweise. Im mittleren Teil die 16 Hexadezimalwerte dazu.

Und ja, nichtanzeigbare Werte (von Dir als Salat bezeichnet) sind vollkommen normal und in Ordnung.

Ein MD5-Hash ist ein Binärwert und keine (unverarbeitet) sinnvoll anzeigbare Zeichenfolge. Es ist kein String.

Der MD5-Hash des Programmes, an dem ich gerade arbeite ist zur Zeit:
Code:
-š³úc;o6¦¥,1<4;
(Das vorletzte Zeichen kann hier nicht dargestellt werden.)

Hexadezimal:
Code:
2D 9A B3 FA 63 3B 6F 36 A6 A5 2C 31 3C 34 06 3B

himitsu 2. Mai 2017 16:16

AW: DEC 5.2 String hashen?
 
Delphi-Referenz durchsuchenBinToHex

TGUID hat zufällig gleich viele Bytes wie ein MD5 ... ein Schelm, wer das einfach mal castet.

a.def 2. Mai 2017 18:24

AW: DEC 5.2 String hashen?
 
Ok das bedeutet also, dass man, wenn man einen Hash erzeugen möchte, eben auch nicht mit TBytes arbeiten kann.
Ich dachte nur ich ändere alles auf TBytes um, da im anderen Thread ja empfohlen wurde von String weg zu TBytes zu gehen.

nahpets 2. Mai 2017 19:21

AW: DEC 5.2 String hashen?
 
String ist aber auch nicht sinnvoll.

Wenn man 'nen Hash auf 'ne Exe machen will, geht man sie bytewesie durch.

TFileStream oder TMemoryStream dürften hier eher die Mittel der Wahl sein.

Unter Delphi 7 nutze ich diese Unit: https://sourceforge.net/p/lazarus-cc...hes/dcpmd5.pas

Das geht dann ungefähr so:
Delphi-Quellcode:
function TfmMain.GetMD5(st : TMemoryStream) : String;
var
  Digest       : array[0..15] of byte;
  i            : Integer;
  iPos         : Integer;
  md5           : TDCP_md5;
begin
  md5         := TDCP_md5.Create(Self);
  iPos       := st.Position;
  st.Position := 0;
  md5.Init;
  md5.UpdateStream(st,st.Size);
  md5.Final(Digest);
  Result := '';
  for i := 0 to 15 do Result := Result + IntToHex(Digest[i],2);
  st.Position := iPos;
  md5.Free;
end;
MD5 an 'ne Datei anhängen:
Delphi-Quellcode:
var
  Digest       : array[0..15] of byte;
  i            : Integer;
  iPos         : Integer;
  md5           : TDCP_md5;
begin
  md5 := TDCP_md5.Create(Self);
  sf := tFileStream.Create(ParamStr(0),fmOpenReadWrite);
  md5.Init;
  md5.UpdateStream(sf,sf.Size);
  md5.Final(Digest);
  sf.Position := sf.Size;
  for i := 0 to 15 do sf.Write(Digest[i],1);
  sf.Free;
  md5.Free;
end;
In neueren Delphis gibt es dashier: http://docwiki.embarcadero.com/Libra...hBytesFromFile

Ich rate jetzt mal, es könnte so ein Einzeiler sein:
Delphi-Quellcode:
ShowMessage(TEncoding.ANSI.GetString(System.Hash.THashMD5.GetHashBytesFromFile(ParamStr(0)));

Das Ergebnis davon an 'ne Datei zu hängen, dürften dann kein Problem mehr sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:00 Uhr.
Seite 3 von 12     123 45     Letzte »    

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