So Einfach Lässt Sich Die CRC-Prüfsumme Berechnen (CRC32 - CRC16 - CRC8)

Inhaltsverzeichnis:

So Einfach Lässt Sich Die CRC-Prüfsumme Berechnen (CRC32 - CRC16 - CRC8)
So Einfach Lässt Sich Die CRC-Prüfsumme Berechnen (CRC32 - CRC16 - CRC8)

Video: So Einfach Lässt Sich Die CRC-Prüfsumme Berechnen (CRC32 - CRC16 - CRC8)

Video: So Einfach Lässt Sich Die CRC-Prüfsumme Berechnen (CRC32 - CRC16 - CRC8)
Video: Контрольная сумма crc + modbus rtu 2024, April
Anonim

Für die Berechnung der CRC-Prüfsumme gibt es im Internet viele Möglichkeiten. Aber was genau ist eine Prüfsumme und warum wird sie so berechnet? Lass es uns herausfinden.

So einfach lässt sich die CRC-Prüfsumme berechnen (CRC32 - CRC16 - CRC8)
So einfach lässt sich die CRC-Prüfsumme berechnen (CRC32 - CRC16 - CRC8)

Anleitung

Schritt 1

Kommen wir zunächst ein wenig zur Theorie. Was genau ist CRC? Kurz gesagt, dies ist eine der Varianten der Prüfsummenberechnung. Prüfsumme ist ein Verfahren zur Überprüfung der Integrität der empfangenen Informationen auf der Empfängerseite bei der Übertragung über Kommunikationskanäle. Eine der einfachsten Prüfungen besteht beispielsweise darin, das Paritätsbit zu verwenden. Dies ist der Fall, wenn alle Bits der übertragenen Nachricht aufsummiert werden, und wenn die Summe gerade ist, wird 0 an das Ende der Nachricht angehängt, wenn sie ungerade ist, dann 1. Beim Empfang wird die Summe der Nachrichtenbits werden ebenfalls gezählt und mit dem empfangenen Paritätsbit verglichen. Unterscheiden sie sich, so traten Fehler bei der Übertragung auf und die übertragenen Informationen waren verzerrt.

Diese Methode zur Erkennung von Fehlern ist jedoch sehr informativ und funktioniert nicht immer, weil wenn mehrere Bits der Nachricht verzerrt sind, kann sich die Parität der Summe nicht ändern. Daher gibt es viele weitere "fortgeschrittene" Prüfungen, einschließlich CRC.

Tatsächlich ist CRC keine Summe, sondern das Ergebnis der Division einer bestimmten Informationsmenge (Informationsnachricht) durch eine Konstante oder vielmehr der Rest einer Division einer Nachricht durch eine Konstante. Die CRC wird jedoch historisch auch als "Prüfsumme" bezeichnet. Jedes Bit der Nachricht trägt zum CRC-Wert bei. Das heißt, wenn sich während der Übertragung mindestens ein Bit der ursprünglichen Nachricht ändert, ändert sich auch die Prüfsumme, und zwar erheblich. Dies ist ein großes Plus einer solchen Überprüfung, da Sie damit eindeutig feststellen können, ob die ursprüngliche Nachricht während der Übertragung verzerrt wurde oder nicht.

Schritt 2

Bevor wir mit der Berechnung des CRC beginnen, ist noch etwas mehr Theorie erforderlich.

Was ist die ursprüngliche Nachricht sollte klar sein. Es ist eine zusammenhängende Folge von Bits beliebiger Länge.

Durch welche Konstante sollten wir die ursprüngliche Nachricht teilen? Diese Zahl ist ebenfalls beliebig lang, aber normalerweise werden Vielfache von 1 Byte verwendet - 8, 16 und 32 Bit. Es ist nur einfacher zu zählen, weil Computer mit Bytes arbeiten, nicht mit Bits.

Die Teilerkonstante wird normalerweise als Polynom (Polynom) wie folgt geschrieben: x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0. Der Grad der Zahl "x" bedeutet hier die Position des Eins-Bits in der Zahl, beginnend bei Null, und das höchstwertige Bit gibt den Grad des Polynoms an und wird bei der Interpretation der Zahl verworfen. Das heißt, die zuvor geschriebene Zahl ist nichts anderes als (1) 00000111 in binärer Form oder 7 in dezimaler Form. In Klammern habe ich die implizite höchstwertige Ziffer der Zahl angegeben.

Hier ist ein weiteres Beispiel: x ^ 16 + x ^ 15 + x ^ 2 + x ^ 0 = (1) 1000000000000101 = 0x8005 = 32773.

Normalerweise werden einige Standardpolynome für verschiedene Arten von CRCs verwendet.

Schritt 3

Wie berechnet man die Prüfsumme? Es gibt ein grundlegendes Verfahren - das Aufteilen einer Nachricht in ein Polynom "frontal" - und seine Modifikationen, um die Anzahl der Berechnungen zu reduzieren und dementsprechend die CRC-Berechnung zu beschleunigen. Wir werden uns die grundlegende Methode ansehen.

Im Allgemeinen wird die Division einer Zahl durch ein Polynom nach folgendem Algorithmus durchgeführt:

1) ein mit Nullen gefülltes Array (Register) wird erstellt, dessen Länge der Länge der Polynombreite entspricht;

2) die ursprüngliche Nachricht wird mit Nullen in den niedrigstwertigen Bits in einer Menge gleich der Anzahl der Bits des Polynoms ergänzt;

3) ein höchstwertiges Bit der Nachricht wird in das niedrigstwertige Bit des Registers eingegeben und ein Bit wird aus dem höchstwertigen Bit des Registers verschoben;

4) wenn das erweiterte Bit gleich "1" ist, dann werden die Bits in denjenigen Registerbits invertiert (XOR-Operation, exklusives ODER), die denen im Polynom entsprechen;

5) wenn noch Bits in der Nachricht vorhanden sind, gehe zu Schritt 3);

6) Wenn alle Bits der Nachricht in das Register eingetreten sind und von diesem Algorithmus verarbeitet wurden, verbleibt der Rest der Division im Register, das ist die CRC-Prüfsumme.

Die Abbildung veranschaulicht die Division der ursprünglichen Bitfolge durch die Zahl (1) 00000111 oder das Polynom x ^ 8 + x ^ 2 + x ^ 1 + x ^ 0.

Schematische Darstellung der CRC-Berechnung
Schematische Darstellung der CRC-Berechnung

Schritt 4

Es gibt noch ein paar zusätzliche Berührungen. Wie Sie vielleicht bemerkt haben, kann die Nachricht durch eine beliebige Zahl geteilt werden. Wie wählt man es aus? Es gibt eine Reihe von Standardpolynomen, die verwendet werden, um den CRC zu berechnen. Für CRC32 könnte es beispielsweise 0x04C11DB7 sein und für CRC16 könnte es 0x8005 sein.

Außerdem können Sie in das Register zu Beginn der Berechnung keine Nullen, sondern eine andere Zahl schreiben.

Außerdem können sie während der Berechnungen unmittelbar vor der Ausgabe der endgültigen CRC-Prüfsumme durch eine andere Zahl geteilt werden.

Und das Letzte. Bytes der Nachricht beim Schreiben in das Register können als höchstwertiges Bit "vorwärts" und umgekehrt als niedrigstwertiges Bit platziert werden.

Schritt 5

Lassen Sie uns auf der Grundlage all dessen eine Basic. NET-Funktion schreiben, die die CRC-Prüfsumme berechnet, indem eine Reihe von Parametern verwendet wird, die ich oben beschrieben habe, und den CRC-Wert als 32-Bit-Zahl ohne Vorzeichen zurückgibt.

Public Shared Function GetCrc (ByVal bytes As Byte (), ByVal poly As UInteger, Optional ByVal width As Integer = 32, Optional ByVal initReg As UInteger = & HFFFFFFFFUI, Optional ByVal finalXor As UInteger = & HFFFFFFFUI, Optional ByVal reverseBytes, Optional Boolean ByVal reverseCrc As Boolean = True) As UInteger

Dim widthInBytes As Integer = width / 8

'Nachrichtenbreite mit Nullen ergänzen (Berechnung in Byte):

ReDim Preserve bytes (bytes. Length - 1 + widthInBytes)

'Erzeuge eine Bit-Warteschlange aus der Nachricht:

Dim msgFifo als neue Warteschlange (von Boolean) (bytes. Count * 8 - 1)

Für jedes b als Byte in Bytes

Dim ba als neues BitArray ({b})

Wenn reverseBytes Dann

Für i As Integer = 0 bis 7

msgFifo. Enqueue (ba (i))

Nächster

Anders

Für i As Integer = 7 bis 0 Schritt -1

msgFifo. Enqueue (ba (i))

Nächster

Ende Wenn

Nächster

'Erzeuge eine Warteschlange aus den anfänglichen Füllbits des Registers:

Dim initBytes As Byte () = BitConverter. GetBytes (initReg)

Dim initBytesReversed As IEnumerable (Of Byte) = (From b As Byte In initBytes Take widthInBytes). Reverse

Dim initFifo als neue Warteschlange (von Boolean) (Breite - 1)

Für jedes b als Byte in initBytesReversed

Dim ba als neues BitArray ({b})

Wenn nicht reverseBytes Then

Für i As Integer = 0 bis 7

initFifo. Enqueue (ba (i))

Nächster

Anders

Für i As Integer = 7 bis 0 Schritt -1

initFifo. Enqueue (ba (i))

Nächster

Ende Wenn

Nächster

'Shift und XOR:

Dim register As UInteger = 0 'fülle das Breite-Bit-Register mit Nullen.

Tun Sie, während msgFifo. Count> 0

Dim poppedBit As Integer = CInt (Register >> (Breite - 1)) und 1 'vor Schieberegister definieren.

Dim shiftedBit As Byte = Convert. ToByte (msgFifo. Dequeue)

Wenn initFifo. Count> 0 Then

Dim b As Byte = Convert. ToByte (initFifo. Dequeue)

shiftedBit = shiftedBit Xor b

Ende Wenn

registrieren = registrieren << 1

register = register Oder shiftedBit

Wenn poppedBit = 1 Dann

registrieren = registrieren Xor poly

Ende Wenn

Schleife

'Endgültige Konvertierungen:

Dim crc As UInteger = register 'Das Register enthält den Rest der Division == Prüfsumme.

Wenn umgekehrtCrc Dann

crc = reflektieren (crc, Breite)

Ende Wenn

crc = crc Xor finalXor

crc = crc And (& HFFFFFFFFUI >> (32 - Breite)) 'maskieren Sie die niedrigstwertigen Bits.

Rücklauf crc

Endfunktion

Empfohlen: