AGB  ·  Datenschutz  ·  Impressum  







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

DEC 5.2 String hashen?

Ein Thema von a.def · begonnen am 2. Mai 2017 · letzter Beitrag vom 7. Mai 2017
Thema geschlossen
Seite 10 von 12   « Erste     8910 1112      
a.def
(Gast)

n/a Beiträge
 
#91

AW: DEC 5.2 String hashen?

  Alt 5. Mai 2017, 14:40
Zitat:
Du hattest wegen RAM schiesst in die Höhe geschrieben - und ich dachte ich mache dir eine Freude, wenn du siehst, dass dies nicht sein muss.
Keine Sorge das hast du Mein Code ist jetzt so aufgebaut, dass nur noch 1x maximal die Datei geladen wird (statt mehrfach). Vorher habe ich die glaube ich 3x geladen.

Zitat:
Weg mit dem Trim. ich weiss, ich wiederhole mich
Ohne Trim funktioniert das leider nicht. Ich weiß nicht genau warum aber ich schätze Trim entfernt mehr als gut ist.
Wenn ich die Bytes der Datei ohne Trim hashe und später auch ohne Trim wieder auslese und dann hashe, sind die Ergebnisse unterschiedlich. Warum weiß ich nicht.

Edit
-- es funktioniert aber wunderbar bisher

Geändert von a.def ( 5. Mai 2017 um 14:48 Uhr)
 
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#92

AW: DEC 5.2 String hashen?

  Alt 5. Mai 2017, 16:16
Result := THashFunctions_Selftest.CalcHash([B]Trim(TEncoding.ANSI.GetString[/B](aByteStream.Bytes, 0, aByteStream.Size - iHashLengthInBytes))); Warum kannst Du Dich nicht von dem verf***** String trennen?

Siehst Du in dem Beispiel vom Michael II irgendwo einen String oder ein Char?

U.U wäre es ganz vernünftig, wenn Du noch einmal ganz von vorne anfangen würdest.....

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
 
a.def
(Gast)

n/a Beiträge
 
#93

AW: DEC 5.2 String hashen?

  Alt 5. Mai 2017, 16:20
Zitat:
Warum kannst Du Dich nicht von dem verf***** String trennen?
Was soll denn an dem String so schlimm sein? Er wird vollkommen korrekt in meine Exe geschrieben und auch geladen. Was will ich denn mehr?
Ich habe schon alles auf TBytes umgestellt. Aber den Rückgabewert möchte ich dennoch gerne als String haben.

P.S.: kein Grund ausfallend zu werden
 
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#94

AW: DEC 5.2 String hashen?

  Alt 5. Mai 2017, 16:41
a) Ein String(char ist eine Interpretation eines Zahlenwertes. Je nach Codepage und oder anderer Annahme (nutzt Du vllt. EBCDIC?) produziert diese Interpretation beim selben Wert ein anderes Zeichen.
b) ich weiß jetzt nicht was an verflixt so ausfallend ist, aber vllt. ist es besser ich verabschiede mich ins WE.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
 
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
760 Beiträge
 
Delphi 11 Alexandria
 
#95

AW: DEC 5.2 String hashen?

  Alt 5. Mai 2017, 16:46
Hallo a.def,

ich habe dir hier noch rasch die ähnliche Funktion für SHA1 geschrieben:

Delphi-Quellcode:
procedure AddSHA1HashBytes( var lHasher: THashSHA1; const AStream: TStream; von, bis : int64 );
const
   BufferSize = 64*1024;
var
  lStreamBytes: TBytes;
  Lies, SollLesen : int64;
  len : integer;
begin
  if bis >= AStream.size then bis := Astream.size-1;
  if von < 0 then von := 0;
  if bis >= von then
  begin
    setlength(lStreamBytes, BufferSize);
    AStream.Position := von;
    SollLesen := bis-von+1;
    while SollLesen > 0 do
    begin
      if SollLesen >= BufferSize then Lies := BufferSize else Lies := SollLesen;
      len := Astream.ReadData(lStreamBytes, Lies);
      if len = 0 then break;
      dec(SollLesen,len);
      lHasher.Update(lStreamBytes, len);
    end;
  end;
end;



function GetSHA1HashFromFile( aFileName : string; vonbis : array of int64 ) : TBytes;
var f : TFileStream;
   lSHA1: THashSHA1;
   i, len : integer;
   von, bis : int64;

begin
  f := TFileStream.Create( aFileName, fmOpenRead );
 try
  lSHA1 := THashSHA1.Create;
  lSHA1.Reset;
  len := length(vonbis);
  if len < 2 then
  begin
      AddSHA1HashBytes( lSHA1, f, 0, f.Size-1 );
  end
  else
  begin
      i := 0;
      while len-i >= 2 do
      begin
        von := vonbis[i];
        bis := vonbis[i+1];
        if von < 0 then von := f.Size+von;
        if bis < 0 then bis := f.Size+bis;

        AddSHA1HashBytes( lSHA1, f, von, bis);
        inc(i,2);
      end;
  end;
  Result := lSHA1.HashAsBytes;
 finally
  f.Free;
 end;
end;


Wenn du von Byte 0 bis 2000 und von Byte 2001 bis ans Ende hashen willst:

GetSHA1HashFromFile( filename, [0, 2000, 2001, maxint] );

Damit hashst du übers ganze File und erhältst natürlich exakt den gleichen Wert wie via
System.hash.THashSHA1.GetHashBytesFromFile( filename );

Beispiel 2:
Wenn du die 20 Bytes 192435 - 192454 nicht "mithashen" willst:
GetSHA1HashFromFile( filename, [0, 192434, 192455, maxint] );
Wenn du deinen SHA1 Hash Wert h ins Programm schreibst und h ab Position 192435 abgelegt ist, dann ist dies der Aufruf der Wahl .

Beispiel 3:
Ein positiver Wert n wird interpretiert als Fileposition n.
Ein negativer Wert n wird interpretiert als Fileposition fsize+n.

GetSHA1HashFromFile( filename, [0, -21] );

Wenn du zum Beispiel an dein File einen SHA1 Hash (20 Bytes) angehängt hast, dann hashst du in diesem Beispiel über dein File, nicht aber über den angehängten Hash Wert.

Beispiel 4:
Du kannst natürlich über beliebig viele Intervalle hashen, zum Beispiel über drei:
GetSHA1HashFromFile( filename, [0,255, 256+pesig, 256+pesig+peofs-1, -20,maxint] );
Michael Gasser

Geändert von Michael II ( 5. Mai 2017 um 19:57 Uhr)
 
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
760 Beiträge
 
Delphi 11 Alexandria
 
#96

AW: DEC 5.2 String hashen?

  Alt 5. Mai 2017, 17:16
Keine Sorge das hast du Mein Code ist jetzt so aufgebaut, dass nur noch 1x maximal die Datei geladen wird (statt mehrfach). Vorher habe ich die glaube ich 3x geladen.
Ich sorge mich aber schon ein wenig. Ich würde mal Pause machen, raus gehen, die 60€ für den Notar abarbeiten und dann wieder ran an den Code .

Stell dir vor, dein File ist grösser als der zur Verfügung stehende Arbeitsspeicher. Dann muss dein OS Daten auf HD auslagern um von der HD lesen zu können .

Mach's mit "Einen Teil des Files lesen" - "Hash weiter rechnen" - "Den nächsten Teil des Files lesen" - "Hash weiter rechnen" - "Den nächsten Teil des Files lesen" - "Hash weiter rechnen" - "Den nächsten Teil des Files lesen" - "Hash weiter rechnen" - .

Dann kannst du deine Prozedur mit gutem Gewissen und entspannt in die freie Wildbahn entlassen.
Michael Gasser
 
a.def
(Gast)

n/a Beiträge
 
#97

AW: DEC 5.2 String hashen?

  Alt 5. Mai 2017, 18:00
Zitat:
Mach's mit "Einen Teil des Files lesen" - "Hash weiter rechnen" - "Den nächsten Teil des Files lesen" - "Hash weiter rechnen" - "Den nächsten Teil des Files lesen" - "Hash weiter rechnen" - "Den nächsten Teil des Files lesen" - "Hash weiter rechnen" - .
Was ich hierbei nicht verstehe... kommt das nicht auf dasselbe raus? Wird hier am Ende nicht auch die ganze Datei eingelesen?

Auszüge aus meinem Code aktuell (den ich auch verstehe). Hier wird der Hash am Ende der Datei gespeichert/geladen:
Delphi-Quellcode:
// Hash setzen
sHash := THashFunctions_Selftest.CalcHash(Trim(TEncoding.ANSI.GetString(aByteStream.Bytes)));
aByteStream.Size := aByteStream.Size + iHashLengthInBytes;
Move(AnsiString(sHash)[1], aByteStream.Bytes[aByteStream.Size - iHashLengthInBytes], iHashLengthInBytes);
aByteStream.SaveToFile(aFileName);
Delphi-Quellcode:
// Dateiinhalt lesen und den Hash bilden
if aByteStream.Size > iHashLengthInBytes then
 begin
  aByteStream.Read(aByteStream.Bytes[0], aByteStream.Size - iHashLengthInBytes);
  Result := THashFunctions_Selftest.CalcHash(Trim(TEncoding.ANSI.GetString(aByteStream.Bytes, 0, aByteStream.Size - iHashLengthInBytes)));
 end
else
 Result := '';
Delphi-Quellcode:
// Am Ende der Datei stehenden Hash auslesen
if aByteStream.Size > iHashLengthInBytes then
 begin
  aByteStream.Position := aByteStream.Size - iHashLengthInBytes;
  aByteStream.Read(aByteStream.Bytes[0], iHashLengthInBytes);
  Result := Trim(TEncoding.ANSI.GetString(aByteStream.Bytes, 0, iHashLengthInBytes));
 end
else
 Result := '';
aByteStream.LoadFromFile(aFileName); wird nur ein einziges Mal ausgeführt, da ich die aktuelle Stream-Instanz immer an den Funktionsaufruf übergebe. Die drei Dinger da oben sthen alle in einer Funktion in der natürlich entschieden wird was man gerade abarbeiten will.

Vielleicht bin ich etwas naiv, dumm bin ich so oder so. Aber wenn beim Programmstart eines ~5MB Programms etwas auf die Festplatte ausgelagert wird, dann sollte sich der PC-Nutzer vielleicht mal Sorgen machen womit er seinen Arbeitsspeicher vollmüllt.

Ich würde gerne deinen Code übernehmen Michael. Aber ich verstehe ihn leider nicht und würde bald auch wieder vergessen was er macht. Mein Code ist zwar vielleicht nur 50% i.O. aber ich verstehe ihn.

Und bevor du dich wieder aufregst p80286, ja. Ich würde gerne vom String weg. Aber a) meinen Code beibehalten und b) vom String weg, das klappt bei mir halt nicht.
Die Lösung da oben funktioniert absolut 1A bisher.
 
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
760 Beiträge
 
Delphi 11 Alexandria
 
#98

AW: DEC 5.2 String hashen?

  Alt 5. Mai 2017, 20:08
... Aber wenn beim Programmstart eines ~5MB Programms etwas auf die Festplatte ausgelagert wird, dann sollte sich der PC-Nutzer vielleicht mal Sorgen machen womit er seinen Arbeitsspeicher vollmüllt.
Ich meinte damit nur: Du solltest beim Programmieren immer auch an den Speicher denken... wenn du das ganze File reinlädst, dann könnte das viel Speicher kosten.
Michael Gasser
 
Michael II

Registriert seit: 1. Dez 2012
Ort: CH BE Eriswil
760 Beiträge
 
Delphi 11 Alexandria
 
#99

AW: DEC 5.2 String hashen?

  Alt 5. Mai 2017, 20:38
Hallo a.def

das hilft eventuell.

MD5 und SHA1 Hash Algorithmen sind absichtlich so konstruiert, dass du nicht von Anfang an das ganze Argument (= alle Filedaten) benötigst.
D.h. du kannst das File nach und nach lesen und jederzeit mit Update den Hash Wert der bereits gelesenen Filedaten berechnen. Du hast also nach jedem Schritt zwei Argumente um fortzufahren mit deiner Berechnung, den momentanen Hash Wert und die noch zu lesenden Filedaten.
Wenn du jeweils nur 128KB Filedaten liest, dann benötigst du an Daten nur diese 128KB im Arbeitsspeicher und ein paar Bytes für den Hash Wert.



Hier ein Beispiel mit MD5 (mit SHA1 läuft's genau "gleich"):

Mit

procedure SchreibeMD5HashAnsEndeDesFiles( const filename : string );

schreibst du die HashBytes ans Ende des Files:

Delphi-Quellcode:
procedure HashAnsEndeDesFilesSchreiben( filename : string; hash : TBytes );
var f : TFileStream;
begin
  f := TFileStream.Create( filename, fmOpenWrite );
 try
  f.Position := f.Size;
  f.Write( hash[0], length( hash ) );
 finally
  f.Free;
 end;
end;


procedure SchreibeMD5HashAnsEndeDesFiles( const filename : string );
var hash, hash2 : TBytes;
begin
  hash := System.hash.THashMD5.GetHashBytesFromFile( filename ); // Die in Delphi System.Hash definierte Funktion
  // hash2 := GetMD5HashFromFile( filename , [] ); // Du könntest auch "unsere" verwenden
  HashAnsEndeDesFilesSchreiben( filename, hash );
end;

Mit

function PruefeMD5HashAmEndeDesFiles( const filename : string ) : boolean;

kannst du überprüfen, ob die HashBytes am Ende des Files OK sind.

Delphi-Quellcode:
function LiesHashAmEndeDesFiles( const filename : string; len : integer ) : TBytes;
var f : TFileStream;
begin
  f := TFileStream.Create( filename, fmOpenRead );
 try
  f.Position := f.Size - len ;
  SetLength( Result, len );
  f.Read( Result, len );
 finally
  f.Free;
 end;
end;


function PruefeMD5HashAmEndeDesFiles( const filename : string ) : boolean;
var hashAmFileEnde, hash : TBytes;
begin
  hash := GetMD5HashFromFile( filename, [0,-17] ); // Wir lesen bis size-17, Den Hash Wert size-16..size-1 verarbeiten wir nicht
  hashAmFileEnde := LiesHashAmEndeDesFiles( filename, 16 ); // Wir lesen den Hash Wert am Ende des Files
  Result := CompareMem( hash, hashAmFileEnde, 16 ); // Wir vergleichen den berechneten Wert mit jenem am Fileende
end;


Testroutine:
1. Zuerst werden die Hashbytes ans Ende des Files geschrieben.

2. Hier wird gezeigt, wie du den Hash Wert am Ende des Files überprüfen kannst:

Delphi-Quellcode:
procedure pruefen;
var filename : string;
    allesok : boolean;
begin
  filename := 'C:\Users\Michael\Desktop\1GB.txt';

  // Ans Fileende schreiben:
  SchreibeMD5HashAnsEndeDesFiles( filename ); // 1.
  // Prüfen, ob der HashWert OK ist:
  allesok := PruefeMD5HashAmEndeDesFiles( filename ); // 2.

  ShowMessage( 'Check File : ' + allesok.ToInteger.ToString );
end;
Michael Gasser

Geändert von Michael II ( 5. Mai 2017 um 21:46 Uhr)
 
a.def
(Gast)

n/a Beiträge
 
#100

AW: DEC 5.2 String hashen?

  Alt 5. Mai 2017, 21:56
Ich bin dir wirklich sehr dankbar für alles. Aber leider funktioniert dein Code bei mir nicht.
Für folgendes erhalte ich auch nur Salat
Delphi-Quellcode:
 // _TEST_TEST_D36E844639D6B4B9ADAF9A11C2ABF841CCE43E94C57539C03CC9524545DD8E8D
 ShowMessage( TEncoding.ANSI.GetString(
    GetSHA1HashFromFile(aFileName, [0, -64])
   )
   );
Deine Lösung ist meiner deutlich überlegen das ist klar. Aber ich denke ich bleibe einfach bei meiner. Ich verstehe sie und kann dran rumbasteln wenn was nicht funktioniert.
 
Thema geschlossen
Seite 10 von 12   « Erste     8910 1112      


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 15:46 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