![]() |
CRC32 für einzelne Wörter!
Hallo zusammen!
Ich suche die ![]() Die Boardsuche hab ich schon bemüht, und habe nur CRC32 für komplette Dateien gefunden ![]() Wäre cool wenn da jemand nen code für mich hätte. Thx fes |
Re: CRC32 für einzelne Wörter!
Such mal nach dem DEC von Hagen Reddmann
|
Re: CRC32 für einzelne Wörter!
nen google tuts auch ...
|
Re: CRC32 für einzelne Wörter!
Hmmm, ich hab zwar
![]() |
Re: CRC32 für einzelne Wörter!
Hi,
damit kannst du auch nur einzelne Wörter crc32en^^ |
Re: CRC32 für einzelne Wörter!
:gruebel: :gruebel: hmmmmm... und wo mach ich des genau??
ich werd aus dem programm ned schlau, warscheinlich bin ich zu dumm dafür... :? |
Re: CRC32 für einzelne Wörter!
du rufst auf:
Delphi-Quellcode:
Gruß Hagen
var
Result: LongWord; begin Result := TChecksum_CRC32.CRCString('Wort'); end; |
Re: CRC32 für einzelne Wörter!
hmm....
vielleicht sollte ich noch erwähnen, dass ich der komplette noob bin, wenn es um units einbinden geht.... :oops: :oops: wenn man mir sagen könnte, welche unit ich wo und wie einbinden muss, wäre ich sehr dankbar... |
Re: CRC32 für einzelne Wörter!
Delphi-Quellcode:
Gruß Hagenuses Checksum; |
Re: CRC32 für einzelne Wörter!
aber bitte die anderen units, die schon drin sind, auch drin lassen ;)
also checksum einfach hintendran hängen. wobei man beachten sollte, dass zwischen den einträgen kommas und hinter de mletzten ein strichkomma ist und das so bleiben sollte. :stupid: |
Re: CRC32 für einzelne Wörter!
Ansonsten nimmst du die Unit aus deinem ersten Link. Dort gibt es die Funktion "RecountCRC()" die du benutzen kannst.
Delphi-Quellcode:
Gruß Hagen
function RecountCRC(b: byte; CrcOld: Longint): Longint;
begin RecountCRC := CRCTable[byte(CrcOld xor Longint(b))] xor ((CrcOld shr 8) and $00FFFFFF) end; function CRCString(const Value: String): Cardinal; var I: Integer; begin Result := $FFFFFFFF; // Init Wert der CRC, schau im PHP nach for I := 1 to Length(Value) do Result := RecountCRC(Ord(Value[I]), Result); Result := not Result; // eventl. Finit Wert, schau im PHP nach end; |
Re: CRC32 für einzelne Wörter!
THX!!!
|
Re: CRC32 für einzelne Wörter!
Ist zwar schon etwas älter der Threat aber ich habe gerade genau das gleiche Problem. Habe einen String und möchte gerne eine CRC32 Prüfung machen. Leider ist die Unit vom ersten Link hier im Threat down. Weiß jemand eine Alternative?
|
Re: CRC32 für einzelne Wörter!
als Alternativen hätten wir noch
Hagen's ![]() ![]() ![]() HashLib! v1.03.exe ![]() vieles vieles mehr und im Notfall noch was von mir ![]()
Delphi-Quellcode:
der CRC32-Teil ließe sich auch "einfach" aus dem Projekt extrahieren
Var CRC32: ThxCRC32;
S: String; B: LongWord; CRC32.InitT; // notfalls das Polynom ändern, oder 'ne andere Tabelle laden CRC32.Calc('dein Wort'); S := CRC32.asHexString; //B := CRC32.asBin; // oder CRC32.InitT; // notfalls das Polynom ändern, oder 'ne andere Tabelle laden CRC32.Init; CRC32.Update('dein Wort'); CRC32.Final; S := CRC32.asHexString; //B := CRC32.asBin; |
Re: CRC32 für einzelne Wörter!
Hi himitsu, erstmal danke für die ausführliche Antwort. Am liebsten würde ich auf deinen letzten Vorschlag zurückkommen allerdings weiß ich nicht genau was ich alles aus deinem Projekt benötige. Du schreibst zwar, dass sich der CRC32-Teil auch "einfach" aus dem Projekt extrahieren lassen würde, denke aber, dass dies nicht ganz auf mich zutrifft :)
Zu dem was ich mache: Ich versuche mit der Snoop Component Suite Ethernet Pakete zu generieren. Der aktuelle Stand ist, dass der Rahmen fast komplett ist. Header, Länge und Daten sind bereits zu einem Hexstring verarbeitet. Mir fehlen jetzt "nur" noch die 4byte (CRC32-Checksumme) die ich zum Schluss als Hexstring anfügen möchte. dachte da an sowas:
Delphi-Quellcode:
function crc32(Datastring: String): Integer;
begin (...) end string := string + IntTohex(crc32(string)) |
Re: CRC32 für einzelne Wörter!
Liste der Anhänge anzeigen (Anzahl: 2)
Wenn du nur eine Funktion möchtest, dann mußt du dir allerdings selber was basteln,
da ich meine CRC32-Frunktionen ohne feste HashTabelle erstellt hab und diese muß erst initialisert werden. Nicht wundern, Aufgrund des internen Aufbaus ist wirklich kein freigeben (.Free) nötig. Und abgesehn vom CRC32 wird auch kein (.InitT aka .Create) benötigt.
Delphi-Quellcode:
oder so
Function MyCRC32(Datastring: String): String;
Var CRC32: ThxCRC32; Begin CRC32.InitT; Result := CRC32.Calc(S).asHexString; End aString := aString + MyCRC32(aString);
Delphi-Quellcode:
aber am Effektivsten sähe es dann so aus:
Function MyCRC32(Datastring: String; Polynom: LongWord = $EDB88320): String;
Var CRC32: ThxCRC32; Begin CRC32.InitT(Polynom); Result := CRC32.Calc(S).asHexString; End aString := aString + MyCRC32(aString, $12345678); (nicht jedesmal die HashTabelle neu berechnen)
Delphi-Quellcode:
Var CRC32: ThxCRC32;
CRC32.InitT; aString := aString + CRC32.Calc(aString).asHexString; aString := aString + CRC32.Calc(aString).asHexString; aString := aString + CRC32.Calc(aString).asHexString; hab das Ganze auch gleich mal an Delphi 2009 angepaßt und hoff es haben sich keine Fehler beim Umbau eingeschlichen. |
Re: CRC32 für einzelne Wörter!
Hab das gleich mal ausprobiert aber leider kommt bei mir bei allen drei Methoden eine mir bisher unbekannte Fehlermeldung [Pascal Fatal Error] Main.pas(250): F2084 Internal Error: URW821. Dein Beispielprojekt funktioniert allerding.
|
Re: CRC32 für einzelne Wörter!
Wie sieht denn dein TestCode aus und in welcher Delphiversion trat der Fehler auf?
füge mal in FHash_single und deine TestUnit nach dem "Interface" ein "{$INLINE OFF}" ein. (ich weiß jetzt leider nicht, wo dieser Schalter seine Auswirkung zeigt) vielleicht hilft's ja ... es kam anscheinend, im Zusammenhang mit mit einem ähnlichem Fehler, schonmal vor
Delphi-Quellcode:
Interface
{$INLINE OFF} ![]() |
Re: CRC32 für einzelne Wörter!
Also ich benutze Delphi2006. Nachdem ich bei beiden units
Delphi-Quellcode:
eingefügt habe kommt jetzt die Meldung
{$INLINE OFF}
Zitat:
und in meiner Main den Aufruf mit
Delphi-Quellcode:
zu
crcChecksum := MyCRC32(Datastring);
Delphi-Quellcode:
das Programm wird nur dann fertig compiliert wenn ich
// CRC-Prüfsumme berechnen
Function TForm1.MyCRC32(Datastring: String): String; var CRC32: ThxCRC32; begin CRC32.InitT; Result := CRC32.Calc(Datastring).asHexString; end;
Delphi-Quellcode:
auskommmentiere
Result := CRC32.Calc(Datastring).asHexString;
|
Re: CRC32 für einzelne Wörter!
versuch es mal so :gruebel:
Delphi-Quellcode:
Function TForm1.MyCRC32(Datastring: String): String;
var CRC32: ThxCRC32; begin CRC32.InitT; CRC32.Calc(Datastring); Result := CRC32.asHexString; end; |
Re: CRC32 für einzelne Wörter!
Jetzt funktioniert es :) Aber warum das nicht auf einem Wisch geht ist mir schleierhaft. Da wäre ich niemals nicht draufgekommen.
|
Re: CRC32 für einzelne Wörter!
nja, mit neuen Funktionalitäten haben die Compiler anfangs öfters mal kleine Problemchen :stupid:
nach'm Überfliegen der Beschreibung, des oben verlinkten "Advanced Records"-Artikels, hätt ich erstmal vermutet es gibt Probleme, wenn man in soeiner Record-Prozeduren auf wiederum soeine Prozedur zugreift. :? |
Re: CRC32 für einzelne Wörter!
Zum Glück ist es nicht so :) In jedem Fall recht vielen Dank für alles und vor allem für deine Geduld!
|
Re: CRC32 für einzelne Wörter!
Hab da noch eine kurze Frage zu deinem CRC32 selbst. Bei Ethernet ist das ja so
Auszug aus Wikipedia: Zitat:
|
Re: CRC32 für einzelne Wörter!
Solche änderungen mußt du natürlich selber machen (der Code weiß ja nicht was du da berechnen willst und berechnet daher nur das "einfach" CRC32)
PS: ist die "Frame Check Sequence" nicht CRC16? hmmmmmmm? :gruebel: hier klingt es nach CRC16: ![]() aber hier nach CRC32: ![]() nach dem Aufbau in ![]()
Delphi-Quellcode:
(also falls du nicht den ganten FrameBuffer kopieren und darin direct die entsprechenden Stellen invertieren willst)
Var CRC: ThxCRC32;
Temp, FCS: LongWord; CRC.InitT(CRC32Table04); CRC.Init; CRC.Update(@SOF, 1); Temp := not PLongWord(@DestMAC)^; CRC.Update(@Temp, 4); CRC.Update(@DestMAC + 4, 2); Temp := not PLongWord(@SrcMAC)^; CRC.Update(@SrcMAC, 4); CRC.Update(@SrcMAC + 4, 2); CRC.Update(@TypeOrLength, 2) CRC.Update(@Data, DataLength); CRC.Final; FCS := not CRC{.asBin}; |
Re: CRC32 für einzelne Wörter!
Also laut
![]() Zitat:
Aber zu deinem Code: Werden da die jetzt schon die ersten 4 Bytes der MAC-Adresse und das Ergebniss invertiert? Kann deinem Code leider nur minimal folgen, was wohl an meinen rudimentären Pointerkenntnissen liegt :oops: |
Re: CRC32 für einzelne Wörter!
Wie gesagt, ob die Berechnung jetzt so ganz richtg ist, weiß ich nicht ...
- ich glaub irgendwo gelesen zu haben, daß irgendwas am Anfang (evtl, SOF?) nicht mit eingerechnet wird - und dann kommt es ja auch noch auf den Aufbau (deiner Variablen) an ... bin im Beispiel jetzt einfach mal von einzelnen Variablen für die einzelnen Teile der Struktur ausgegangen (und hoff deren Größe richtig gewählt zu haben) - jupp, die ersten 4 Byte der MACs werden schon invertiert, aber das könnte man auch noch entsprechend deinen Typen-/Variablendefinitionen verbessern/optimieren - beim .InitT mußt du aufpassen ... ohne die Richtige Hash-Tabelle wird das Ergebnis falsch sein CRC32Table04 ist eine vorberechnete Tabelle aus dem Polynom $04C11DB7, welches zwar vorwiegend bei AUTODIN II, Ethernet und &FDDI verwendet wird, aber ob das nun in diesem Fall stimmt :?:
Delphi-Quellcode:
wie gesagt, man könnte auch eine Kopie deines Frames(der ganzen Struktur) machen, darin die 2*4 Byte invertieren und dann über alles zusammen den Hash anlegen ... das geht aber nur/besser, wenn alles schon schön in einer Struktur (z.B. als Record) vorliegt
Temp := not PLongWord(@DestMAC)^; // 1. 4 Byte in LongInt(=4 Byte) konvertieren und invertieren(not)
CRC.Update(@Temp, 4); // diese 4 invertierten Byte ins CRC einberechnen CRC.Update(@DestMAC + 4, 2); // die letzen 2 Byte einberechnen FCS := not CRC.asBin; // hier wird das Ergebnis invertiert |
Re: CRC32 für einzelne Wörter!
Also ich hab mich jetzt nochmal drangesetzt und deinen Vorschlag versucht zu übernehmen. Doch leider kommt bei mir die Meldung
Zitat:
Delphi-Quellcode:
CRC.Update(@DestMAC + 4, 2);
Delphi-Quellcode:
Das SOF wird in die CRC-Berechnugn nicht einbezogen deshalb hab ich es entfernt.
//globale Variablen:
var DestMac,SrcMAC,TypeOrLength,Data: String; // CRC-Prüfsumme berechnen Function TForm1.MyCRC32: String; Var CRC: ThxCRC32; Temp, FCS: LongWord; begin CRC.InitT(CRC32Table04); CRC.Init; Temp := not PLongWord(@DestMAC)^; // 4 Byte in LongInt(=4 Byte) konvertieren und invertieren(not) CRC.Update(@Temp, 4); // diese 4 invertierten Byte ins CRC einberechnen CRC.Update(@DestMAC + 4, 2); // die letzen 2 Byte einberechnen HIER TAUCHT DER FEHLER AUF Temp := not PLongWord(@SrcMAC)^; CRC.Update(@SrcMAC, 4); CRC.Update(@SrcMAC + 4, 2); CRC.Update(@TypeOrLength, 2); CRC.Update(@Data, 46); CRC.Final; FCS := not CRC{.asBin}; // Result := CRC im Hexstring? Result := FCS.asHexstring; end; |
Re: CRC32 für einzelne Wörter!
ja, nicht mit alle Pointern kann man direkt rechnen
z.B.
Delphi-Quellcode:
außerdem zeigt @DestMAC (wenn es ein String ist) nicht auf die Daten (die Zeichen im String), sondern den DatenZeiger (sieht man aber nur, wenn man den internen Aufbau eines Strings kennt)
PAnsiChar(@DestMAC) + 4
// oder Pointer(Integer(@DestMAC) + 4) // und bei Strings @DestMAC[1] + 1 PS: DestMac, SrcMAC und TypeOrLength sind hier bestimmt als Binärwerte einzurechnen (es ist wohl sehr unwahrscheinlich, daß die Ethernet-Contoler intern mit Strings arbeiten)
Delphi-Quellcode:
Var DestMAC: Array[0..5] of Byte;
SrcMAC: Array[0..5] of Byte; //VLANTag: LongWord; TypeOrLength: Word; Data: Array[0..1499] of Byte; CRC: ThxCRC32; RecCRC, Temp: LongWord; Begin CRC.InitT(CRC32Table04); CRC.Init; Temp := not PLongWord(@DestMAC[0])^; CRC.Update(@Temp, 4); CRC.Update(@DestMAC[4], 2); Temp := not PLongWord(@SrcMAC[0])^; CRC.Update(@Temp, 4); CRC.Update(@SrcMAC[4], 2); //CRC.Update(@VLANTag, 4); CRC.Update(@TypeOrLength, 2); CRC.Update(@Data[0], DataLen); CRC.Final; RecCRC := not CRC.asBin; End;
Delphi-Quellcode:
Var Rec, TempRec: packed Record
DestMAC: Array[0..5] of Byte; SrcMAC: Array[0..5] of Byte; //VLANTag: LongWord; TypeOrLength: Word; Data: Array[0..1499] of Byte; End; CRC: ThxCRC32; RecCRC: LongWord; Begin TempRec := Rec; // irgendwie kopieren CRC.InitT(CRC32Table04); CRC.Init; For i := 0 to 3 do Begin TempRec.DestMAC[i] := not TempRec.DestMAC[i]; TempRec.SrcMAC[i] := not TempRec.SrcMAC[i]; End; CRC.Update(@TempRec, 6+6{+4}+2+DataLen); CRC.Final; RecCRC := not CRC.asBin; End; |
Re: CRC32 für einzelne Wörter!
Also ich würde das ja gerne so mit dem record machen allerdings weiß ich nicht genau wie ich meine MAC-Adressen in Hex umwandel und in das Array of Byte speichern soll. Weil das muss ich ja machen, oder?
|
Re: CRC32 für einzelne Wörter!
Das Array of Byte könnte man ja noch ändern.
ind welchem Formt liegen denn deine MAC-Adressen vor? |
Re: CRC32 für einzelne Wörter!
Sie wird im Edit eingegeben also als String. Ich habe eigentlich alles als String vorliegen. Da ich die Daten auch im Edit eingebe bzw. Snoop einen String verlangt ist das für mich so komfortabler.
|
Re: CRC32 für einzelne Wörter!
Also mit Wireshark kann man das schön testen. Obwohl ich meine Paket auf 64Byte aufgeblasen habe werden die Rahmen alle als defekt angezeigt, weil eben die CRC-Prüfsume noch nicht korrekt ist.
Edit also ohne den Invertierungskrahm funktioniert das ja ... nur mit eben leider nicht :? |
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz