AGB  ·  Datenschutz  ·  Impressum  







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

Mini-SHA1

Ein Thema von himitsu · begonnen am 2. Jun 2010 · letzter Beitrag vom 6. Feb 2013
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#1

Mini-SHA1

  Alt 2. Jun 2010, 14:50
Vielleicht hat es schonmal jemand gesehn (hab's ja in einigen Projekten verbaut).
Delphi-Quellcode:
type
  SHA_CTX = packed Record
    Unknown: Array[0.. 5] of LongWord;
    State: Array[0.. 4] of LongWord;
    Count: UInt64;
    Buffer: Array[0..63] of Byte;
  End;
  pSHA_CTX = ^SHA_CTX;
  SHA_RES = Array[0..4] of LongWord;

Procedure SHA_CTX.Init(Var Context: SHA_CTX); StdCall;
  External 'advapi32.dllName 'A_SHAInit';

Procedure SHA_CTX.Update(Var Context: SHA_CTX; Input: Pointer; inLen: LongWord); StdCall;
  External 'advapi32.dllName 'A_SHAUpdate';

Procedure SHA_CTX.GetResult(Var Context: SHA_CTX; Out Result: SHA_RES); StdCall;
  External 'advapi32.dllName 'A_SHAFinal';
Und da ich Records so sehr mag, hatte ich's jetzt nochmal etwas überarbeitet
Delphi-Quellcode:
type
{$ALIGN 4}
  TSHA1Res = Array[0..4] of LongWord;
  TSHA1 = Packed Record
    Procedure Init; StdCall;
    Procedure Update (Input: Pointer; inLen: LongWord); StdCall;
    Procedure Finalize(Result: TSHA1Res); StdCall;
    Function doFinalize: TSHA1Res; Inline;

    Class Function toBase64(Res: TSHA1Res): String; Static;
    Class Function Calc (Input: Pointer; inLen: LongWord): TSHA1Res; Static;
    Class Function CalcX (Input: Pointer; inLen: LongWord): String; Static;
  Public
    Unknown: Array[0.. 5] of LongWord;
    State: Array[0.. 4] of LongWord;
    Count: UInt64;
    Buffer: Array[0..63] of Byte;
  End;
  {$ALIGN 8}

Procedure TSHA1.Init{Var Context: SHA_CTX}; StdCall;
  External 'advapi32.dllName 'A_SHAInit';

Procedure TSHA1.Update{Var Context: SHA_CTX; Input: Pointer; inLen: LongWord}; StdCall;
  External 'advapi32.dllName 'A_SHAUpdate';

Procedure TSHA1.Finalize{Var Context: SHA_CTX; Out Result: SHA_RES}; StdCall;
  External 'advapi32.dllName 'A_SHAFinal';

Function TSHA1.doFinalize: TSHA1Res;
  Begin
    Finalize(Result);
  End;

Class Function TSHA1.toBase64(Res: TSHA1Res): String;
  Const Base64: Array[0..63] of Char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

  Var R: packed Record Res: TSHA1Res; Fill: AnsiChar; End;
    A: packed Array[0..20] of Byte absolute R;
    i: Integer;

  Begin
    R.Res := Res;
    R.Fill := '=';
    SetLength(Result, 28);
    For i := 0 to 6 do Begin
      Result[i * 4 + 1] := Base64[ (A[i * 3 + 0] shr 2) and 63];
      Result[i * 4 + 2] := Base64[((A[i * 3 + 0] shl 4) or (A[i * 3 + 1] shr 4)) and 63];
      Result[i * 4 + 3] := Base64[((A[i * 3 + 1] shl 2) or (A[i * 3 + 2] shr 6)) and 63];
      Result[i * 4 + 4] := Base64[ A[i * 3 + 2] and 63];
    End;
    Result[28] := '=';
  End;

Class Function TSHA1.Calc(Input: Pointer; inLen: LongWord): TSHA1Res;
  Var X: TSHA1;

  Begin
    X.Init;
    X.Update(Input, inLen);
    X.Finalize(Result);
  End;

Class Function TSHA1.CalcX(Input: Pointer; inLen: LongWord): String;
  Begin
     Result := toBase64(Calc(Input, inLen));
  End;
Delphi-Quellcode:
var
  SHA1: TSHA1;
  Result: TSHA1Res

SHA1.Init;
SHA1.Update(P, len);
SHA1.Finalize(Result);
// irgendwas mit Result machen
ShowMessage(TSHA1.CalcX(P, len));
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
SittingDuck

Registriert seit: 11. Jan 2006
Ort: Leverkusen
159 Beiträge
 
Delphi 2010 Professional
 
#2

AW: Mini-SHA1

  Alt 15. Okt 2011, 18:17
Hallo zusammen ...

Ich wollte die Routine von himitsu 'mal eben' umstellen auf die Ausgabe im Hex-Format. In der Bit-Schiebe-Routine stimmt aber was nicht. Dem entsprechend ist das Ergebnis dann leider auch falsch. Ich habe den Base64 Teil einfach mal auskommentiert.

Delphi-Quellcode:
class function TSHA1.toBase64(Res: TSHA1Res): String;
//const Base64: array[0 .. 63] of Char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
const HexTable: array[0 .. 15] of Char = '0123456789ABCDEF';
var R: packed record Res: TSHA1Res; Fill: AnsiChar; end; A: packed array[0..20] of Byte absolute R; i: Integer;
begin
 R.Res := Res; R.Fill := '='; SetLength(Result, 28);
    for i := 0 to 6 do begin
// Result[i * 4 + 1] := Base64[ (A[i * 3 + 0] shr 2) and 63];
// Result[i * 4 + 2] := Base64[((A[i * 3 + 0] shl 4) or (A[i * 3 + 1] shr 4)) and 63];
// Result[i * 4 + 3] := Base64[((A[i * 3 + 1] shl 2) or (A[i * 3 + 2] shr 6)) and 63];
// Result[i * 4 + 4] := Base64[ A[i * 3 + 2] and 63];

      Result[i * 4 + 1] := HexTable[ (A[i * 3 + 0] shr 2) and 15];
      Result[i * 4 + 2] := HexTable[((A[i * 3 + 0] shl 4) or (A[i * 3 + 1] shr 4)) and 15];
      Result[i * 4 + 3] := HexTable[((A[i * 3 + 1] shl 2) or (A[i * 3 + 2] shr 6)) and 15];
      Result[i * 4 + 4] := HexTable[ A[i * 3 + 2] and 15];

 end;
end;
Wo liegt mein Fehler? Danke schon mal für die Hilfe ...
Ciao ... SittingDuck
iPhone Backup und mehr: iTwin v3.9 Beta ... Alternative Startleiste: Launcher v3.8 !
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#3

AW: Mini-SHA1

  Alt 15. Okt 2011, 20:09
Wo liegt mein Fehler?
Ersteinmal mußt du verstehen, was Hexadezumal und Base64 eigentlich ist.

Bei Base64 hat jedes "kodierte" Zeichen 64 Werte, wärend es bei Hexadezimal nur 16 Werte sind.
Außerdem ist dabei natürlich der kodierte String länger ... mehr Zeichen, da ja weniger Daten pro Zeichen vorhanden sind.
Base64 = 28 Zeichen (4 Zeichen pro 3 Byte)
Hex = 40 Zeichen (2 Zeichen pro Byte, also 6 Zeichen pro 3 Byte)

Du hast jetzt versucht 64 Werte auf ein 16-Zeichen Array loszulassen, was natürlich schief laufen muß.
PS: Schalte mal die Bereichsprüfung in deinen Projektoptionen an.
(und schon wäre dir das Problem von selber aufgefallen )

Und dann war natürlich der String zu kurz.

Delphi-Quellcode:
Class function TSHA1.toHex(Res: TSHA1Res): String;
  Const HexTable: array[0..15] of Char = '0123456789ABCDEF';

  Var A: packed array[0..19] of Byte absolute Res;
    i: Integer;

  Begin
    SetLength(Result, 40);
    Bor i := 0 to 19 do Begin
      Result[i * 2 + 1] := HexTable[A[i] shr 4];
      Result[i * 2 + 2] := HexTable[A[i] and 15];
    End;
  End;
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (15. Okt 2011 um 20:23 Uhr)
  Mit Zitat antworten Zitat
SittingDuck

Registriert seit: 11. Jan 2006
Ort: Leverkusen
159 Beiträge
 
Delphi 2010 Professional
 
#4

AW: Mini-SHA1

  Alt 16. Okt 2011, 14:11
Super himitsu ... Danke für Deinen Input, da habe ich es mir wohl etwas zu leicht gemacht. Irgendwas stimmt da aber immer noch nicht.

Wenn ich per
Delphi-Quellcode:
var s, h: String;

 s := 'abc';
 h := TSHA1.CalcBase(PChar(s), Length(s));
den Hash von dem String 'abc' ermitteln möchte dann sollte eigentlich das rauskommen:
'A9993E364706816ABA3E25717850C26C9CD0D89D' ... ich erhalte aber das hier:
'4A3DEC2D1F8245280855C42DB0EE4239F917FDB8' ...

Auf welchem abenteuerlichen Holzweg bin ich jetzt wieder gelandet ?!?
Danke schonmal im Vorraus
Ciao ... SittingDuck
iPhone Backup und mehr: iTwin v3.9 Beta ... Alternative Startleiste: Launcher v3.8 !
  Mit Zitat antworten Zitat
gammatester

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

AW: Mini-SHA1

  Alt 16. Okt 2011, 19:55
Ich vermute Du bist vom Unicode-Desaster erwischt worden: 4A3DEC2D1F8245280855C42DB0EE4239F917FDB8 ist der SHA1-Digest der Bytefolge $61,$00,$62. Da Du D2010 benutzt, ist der String 'abc' doch wohl ein Unicodestring. Hashen von Strings halte ich für sinnlos und gefährlich. Kryptographische Hasfunktionen arbeiten auf Bit-/Bytefolgen und die Testwerte sind entsprechend. Für den Testvektor $61,$62,$63 liefert SHA1 den Wert A9993E364706816ABA3E25717850C26C9CD0D89D. Wenn Du unbedingt mit Strings arbeiten willst, nimm für solche Sachen Ansistrings
Delphi-Quellcode:
var
  s: ansistring:
  h: String;

 s := 'abc';
 h := TSHA1.CalcBase(PChar(s), Length(s));
sollte den Testwert ergeben. Wenn Du unbedingt Strings haschen willst, solltest Du TSHA1.CalcBase(PChar(s), Length(s)*Sizeof(char)); verwenden.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.063 Beiträge
 
Delphi 12 Athens
 
#6

AW: Mini-SHA1

  Alt 16. Okt 2011, 21:08
Den AnsiString natürlich mit PAnsiChar, ansonsten war's gut erklärt
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
SittingDuck

Registriert seit: 11. Jan 2006
Ort: Leverkusen
159 Beiträge
 
Delphi 2010 Professional
 
#7

AW: Mini-SHA1

  Alt 28. Okt 2011, 14:39
Vielen Dank für Eure ausführliche Hilfe. Nun läuft alles perfekt. Eins ist klar ... ohne dieses Forum wäre ich ganz oft total aufgeschmissen!
Ciao ... SittingDuck
iPhone Backup und mehr: iTwin v3.9 Beta ... Alternative Startleiste: Launcher v3.8 !
  Mit Zitat antworten Zitat
H3llsing

Registriert seit: 12. Nov 2008
96 Beiträge
 
Delphi 2010 Enterprise
 
#8

AW: Mini-SHA1

  Alt 6. Feb 2013, 13:19
Hallo, ich wollte nochmal das uralte Thema aufgreifen.

Was für ein Datentyp ist denn Bor? ByteOfRecord?
Wie sollte man das initialisieren?

Zitat:
Delphi-Quellcode:
Class function TSHA1.toHex(Res: TSHA1Res): String;
  Const HexTable: array[0..15] of Char = '0123456789ABCDEF';

  Var A: packed array[0..19] of Byte absolute Res;
    i: Integer;

  Begin
    SetLength(Result, 40);
    Bor i := 0 to 19 do Begin
      Result[i * 2 + 1] := HexTable[A[i] shr 4];
      Result[i * 2 + 2] := HexTable[A[i] and 15];
    End;
  End;

Vielen Dank für eure Hilfe
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.768 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Mini-SHA1

  Alt 6. Feb 2013, 13:28
ich denke das sollte For heißen - macht für mich jedenfalls Sinn.

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
H3llsing

Registriert seit: 12. Nov 2008
96 Beiträge
 
Delphi 2010 Enterprise
 
#10

AW: Mini-SHA1

  Alt 6. Feb 2013, 14:07
Autsch!
Natürlich! Ich mach erstmal Mittag. Vielen dank

eine Frage zu der Unicode-Umwandlung hätt ich dann noch:
Warum ist das nicht das gleiche ?

Delphi-Quellcode:
var
  s: String;
  p: PansiChar;
begin
  s := 'abc';
  p := pAnsiChar(s);
end
wie
  p := 'abc';
Alles klar weils AnsiString und nicht String sein muss

Geändert von H3llsing ( 6. Feb 2013 um 14:29 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort


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 01:18 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