Hallo, ich versuche grade auf einer SPS eine CRC32 Funktion zu schreiben, da die SPS Libs nur einen CRC 16 hergeben. Mein Code funktioniert zwar grundsätzlich, leider stimmt mein CRC32 nicht mit den üblichen Verfahren überein. Ich habe zu Testzwecken mal den String "1234" als Daten hergenommen. Mein Polynom ist 16#04C11DB7, binär also 1 0000 0100 1100 0001 0001 1101 1011 0111. An meine Daten (chars, also 4 Byte) hänge ich 32 Nullen an. Nun gehe ich her und wende das 33 bit Polynom mit XOR auf die Daten an, beginnend mit der ersten 1 in den Daten. Vom Ergebnis entferne ich die führenden Nullen und fülle mit den nächsten Bits aus den Daten auf und mach die nächste XOR Verknüpfung mit den neuen Daten. Im Internet habe ich eine Seite gefunden die für CRC32 die binären Operationen Schritt für Schritt anzeigt, mein Programm tut exakt das selbe. Am Ende bleibt ein Rest übrig, der auch exakt dem Wert aus dem Internetbeispiel entspricht. Also so scheint schon mal alles richtig zu sein. Allerdings entspricht das Ergebnis nicht dem Wert, was die üblichen verdächtigen CRC32 Online-Generatoren ausspucken. Nun wird ja bei den Generatoren noch ein Inital Value verwendet und außerdem sind je nach Verfahren noch Optionen wie "RefIn", "RefOut", "XorOut". Damit weiß ich nicht genau wie ich das impelemtieren soll. Kann mir jemand sagen wo meine Fehler liegen und was ich noch implementieren muss um auf das richtige Ergebnis zu kommen? Grüße, Andre
Andre schrieb: > Nun wird ja bei den Generatoren noch ein Inital Value verwendet Das ist der Startwert Deines CRC-Registers, den Du verwenden musst, statt es mit 0 zu initialisieren.
Hm, also aktuell initialisiere ich das CRC Register gar nicht. Ich mache eine XOR Verknüpfung mit den ersten 33 Bit der Daten und dem Polynom, beginnend mit der ersten 1 in den Daten (bzw frame)... Wie schaut eine solche Initialisierung aus? Erst 33 Bit an 1111111..... mit dem Polynom XOR verknüpfen und vom Ergebnis dann führende Nullen entfernen und mit Datenbits auffüllen oder wie darf ich mir das vorstellen? Grüße, Andre
Andre schrieb: > Wie schaut eine solche Initialisierung aus? https://de.wikipedia.org/wiki/Zyklische_Redundanzpr%C3%BCfung#Berechnung_einer_CRC-Pr%C3%BCfsumme_in_C_und_Pascal_bzw._Delphi Dort ist es diese Zeile:
1 | uint32_t crc32 = 0; /* Schieberegister */ |
Andre schrieb: > Hm, > also aktuell initialisiere ich das CRC Register gar nicht vielleicht hilft das? https://stackoverflow.com/questions/2587766/how-is-a-crc32-checksum-calculated
:
Bearbeitet durch User
Hallo, vielen Dank für die Antworten, habs vor Weihnachten noch hingebracht mit den Links aus euren Beiträgen. Da das Thema ja öfter zu finden ist, erkläre ich schnell die Vorgehensweise um evtl anderen Usern helfen zu können. Der CRC32 verfügt standardmäßig über 4 Parameter, welche je nach Variante verwendet werden können oder nicht. Das sind: Initial Value Reverse Input Reverse Output XOR Output Mask Zuerst werden die Daten, aus welchen der CRC32 berechnet werden soll binär umgewandelt. Ist die Option Reverse Input gesetzt, wird jedes Byte jedoch verdreht, das heißt BIT0 kommt an Stelle von BIT7, BIT1 kommt an Stelle von BIT6, BIT2 an Stelle, von BIT5 und so weiter. Anschließend werden an die nun entstandene Bit-Folge 32 Nullen angehangen. Nun werden die ersten 32 Bit der Daten mit ebenfalls 32 Bit langen Initial Value mit XOR verknüpft. Bei einem Initial Value von 16xFFFFFFFF würden alle 32 Bits invertiert werden, bei einem Initial Value von 16x00000000 würden alle 32 Bits so bleiben wie sie sind. Für andere Initial Values ergibt sich ein anderes verhalten. Nun werden von den Daten führende Nullen entfernt, soweit welche vorhanden sind. Anschließend beginnt die Polynomdivision mit dem CRC32 Polynom. Das Polynom ist 33 Bit lang und beginnt immer mit einer 1. Auch beim Standard Polynom (16x04C11DB7) ist das so, die erste 1 wird nur im Polynom nicht geschrieben, da sie standardmäßig immer 1 ist. Es werden also nun 33 Bits der Daten mit den 33 Bits des Polynoms mit XOR verknüpft. Das Ergebnis hat nun mindestens eine führende Null (Da die Daten mit 1 beginnen und auch das Polynom mit 1 beginnt, ergibt das erste Bit immer 0). Die führenden Nullen des Ergebnisses werden nun entfernte und am Ende mit den folgenden Bits aus den Datan aufgefüllt. Nun erfolgt die nächste XOR Verknüpfung mit dem Polynom. Dabei erhält man mindestens wieder eine führende 0. Man verfährt nun so weiter bis man alle Bits der Daten durch hat. Am Ende erhält man den 32 Bit langen CRC32 (das höchste, 33ste Bit ist ja wieder Null und kann entfernt werden). Ist nun noch die Option Reverse Output aktiv werden die kompletten 32 Bit des CRC32 nochmal umgedreht, also BIT1 an Stelle von BIT32 und so weiter. Zu guter Letzt gibt es noch die XOR Output Mask. Diese ist 32 Bit lang. Damit wird nun der CRC32 nochmals XOR verknüpft. Bei einer Output Mask von 0xFFFFFFFF würden auch hier wieder alle Bits invertiert werden, bei 0x00000000 würde das Ergebnis unverändert bleiben, alle anderen Output Masks würden natürlich zu einem anderen Verhalten führen. Ich konnte das so in meiner SPS umsetzten und alle CRC32 mit allen möglichen Optionen stimmen mit den Ergebnissen üblicher Online Generatoren überein. Ich hoffe ich konnte hier dem ein oder anderen, welcher auch in Problem damit hat, weiterhelfen. Grüße
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.