program Rehash; {$APPTYPE CONSOLE} uses SysUtils, Classes, zlib, Math, AnsiStrings, StrUtils, sha1; var ms1, ms2, ms3: TMemoryStream; z: TZCompressionStream; i, j: Integer; b, count: Byte; size: Integer; temp: Cardinal; s2: RawByteString; ctx: TSHA1Context; dig: TSHA1Digest; ba: PByteArray; const Base64: AnsiString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\'; // Achtung: Unterschiedlich! begin try writeln('Snapshot-SHA-1-Hash-Neuberechner (Stand-Alone) // yat.qa // 11. Dezember 2016'); ms1 := TMemoryStream.Create; ms2 := TMemoryStream.Create; ms1.LoadFromFile(paramstr(1)); // Absätze am Ende erkennen Size := ms1.Size; repeat dec(Size); ms1.Position := Size; ms1.ReadBuffer(b, 1); until (b <> $0a) and (b <> $0d); //inc(size); writeln(ms1.Size - Size - 1, ' Bytes am Ende entfernt'); ms1.Position := 0; // BOM erkennen ms1.ReadBuffer(b, 1); if b = $ef then ms1.ReadBuffer(temp, 2) else ms1.Position := 0; // SHA-1 berechnen ms2.CopyFrom(ms1, 5); write('Alter Hash: '); while True do begin ms1.Read(b, 1); if b = $7c then Break; write(AnsiChar(b)); end; ms1.Position := ms1.Position - 1; writeln; //ms1.Position := ms1.Position + 34; sha1init(ctx); ba := ms1.Memory; SHA1Update(ctx, ba[ms1.Position + 1], Size - ms1.Position); ba := nil; // braucht man das? dig := SHA1Final(ctx); ms3 := TMemoryStream.Create; ms3.WriteBuffer(dig, 20); ms3.Position := 0; //for i := 0 to 19 do //write(IntToHex(dig[i], 2)); // Base64-Encoder (binary-safe), feste Größe von 20 Byte (27+1 Zeichen) Count := 3; // Compiler-Blabla write('Neuer Hash: '); for i := 0 to 6 do begin count := Min(20 - i * 3, 3); ms3.ReadBuffer(temp, Count); temp := temp and $ff00 + temp shl 16 + (temp shr 16) and $ff; // Endianness drehen (vereinfacht weil nur 3 Byte verwendet) for j := 0 to Count do begin b := Byte(Base64[(temp shr 18) and $3f + 1]); temp := temp shl 6; ms2.WriteBuffer(b, 1); write(AnsiChar(b)); if b = $5c then begin b := $2F; ms2.WriteBuffer(b, 1); write(AnsiChar(b)); end; end; end; writeln('='); b := $3D; ms2.WriteBuffer(b, 1); ms2.CopyFrom(ms1, Size - ms1.Position + 1); ms2.SaveToFile(paramstr(1) + '.new'); writeln('Erfolgreich neu berechnet!'); except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; readln; end.