Hallo Zusammen, wie im Betreff schon zu vermuten ist, versuche ich seit einiger Zeit die CRC-Berechung für einen Frame (HDLC-Format) zu berechnen. Über eine Software (bzw. Bus-analyzer) lasse ich mir kleine Frames anzeigen. Auf dem Bus werden bspw. die Daten "FA01" versendet und der CRC-Wert dafür ist "B69F". Jetzt habe ich natürlich versucht, den CRC-Wert nachzurechnen: Generatorpolynom: x^16+x^12+x^5+1 = 1000 1000 0001 0000 1 Daten : FA01 = 1111 1010 0000 0001 Ich fange an, den Daten 16 Nullen anzufügen: Daten_mit_nullen = 1111 1010 0000 0001 0000 0000 0000 0000 Nun beginnt die eigentlich Division: Daten_mit_nullen ---------------- ==> Der Rest dieser Division(XOR) ist der CRC-Wert. Generatorpolynom Aber ich komme nicht auf den CRC-Wert "B69F" !! Auch sämtliche Onlinerechner geben mit ständig etwas unterschiedlich aus... Ich habe relativ oft etwas gelesen von "Initialwert" oder "Abschließende XOR-Verknüpfung", aber selbst wenn ich das berücksichtige (sofern ich es denn richtig verstanden habe), komme ich nicht auf den genannten CRC-Wert. Kann es sein, dass ich beim HDLC-Format die Daten vorher drehen muss (also "01FA")? Kann jemand helfen? Ich bedanke mich recht herzlich für eure Hilfe Viele Grüße
:
Bearbeitet durch User
Hi, keine Lösung aber schonmal hier nachgelesen: http://read.pudn.com/downloads138/sourcecode/others/589576/ISO13239.pdf (Ab Seite 13 im Dokumente unter FCS) Gruß
Hallo Narf, vielen Dank für deine Antwort. Hab da mal rein geschaut, aber im Detail wird das leider auch nicht erklärt. Da steht eigentlich nur das, was ich schon wusste. Dennoch vielen Dank!
Bei CRC gibt es n+1 Möglichkeiten. "HDLC" sagt erst einmal nicht viel. Es gibt unterschiedliche Anfangswerte und unterschiedliche Polynome. Und man kann erst das LSB oder das MSB senden. Genormt ist da nichts. Es hilft dir nur probieren (oder den Autor der Software befragen, die das sendet).
Hallo Georg, vielen Dank für deine Antwort. Georg G. schrieb: > Es gibt unterschiedliche Anfangswerte und unterschiedliche Polynome. Und > man kann erst das LSB oder das MSB senden. - Das Polynom ist ja bekannt. - In der Spezifikation des Busses steht, dass man zu erst das MSB sendet. - der Anfangwert ist 0xFFFF ( was auch immer der Anfangswert sein soll ... ) Reicht das aus, um den CRC-Wert zu bestimmen? _________________________________ Ergänzung: Georg G. schrieb: > "HDLC" sagt erst einmal nicht viel Ist im HDLC-Format nicht festgelegt wie die CRC-Wert/Berechnung aussehen soll?
:
Bearbeitet durch User
Moe Espunkt schrieb: > Ist im HDLC-Format nicht festgelegt wie die CRC-Wert/Berechnung aussehen > soll? Damals in Bereich der öffentlichen Netzwerke wurde HDLC/X.25 mit CRC verwendet, das ist standardisiert durch ITU-T: https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-X.25-199610-I!!PDF-E&type=items Kapitel 2.2.7.4.
Moe Espunkt schrieb: > Ist im HDLC-Format nicht festgelegt wie die CRC-Wert/Berechnung aussehen > soll? Leider nein, HDLC beschreibt, wie Frames aussehen (Flag, Daten, CRC, Flag) und wie zB. Bitstuffing gemacht wird. Übrigens, Norm... dein Polynom ist eigentlich typisch für HDLC. Bei Herrn IBM nahm man aber X16 + X15 + X2 + 1. Die CRC-Prüfsumme wird üblicherweise mit 0xffff initialisiert.
Georg G. schrieb: > Übrigens, Norm... dein Polynom ist eigentlich typisch für HDLC. Nennt sich in meinen Unterlagen CCITT CRC. Georg G. schrieb: > Bei > Herrn IBM nahm man aber X16 + X15 + X2 + 1. Und das CRC-16. Da gibts im Netz jede Menge Unterlagen, auch Software. Georg
Wenn ich das ganz theorethisch betrachte, dann müsste doch die CRC-Berechnung folgende sein: Daten+16 Nullen dran FA010000 (hex) -------------------- = ----------------- Generatorpolynom 10001000000100001 (binär) Der Rest dieser Division müsste ja der CRC-Wert sein. Das ganze hab ich mal in Wolfram Alpha eingegeben und es kommt nicht der gewünschte wert von "B69F" raus!! Dabei habe ich mich ganz genau an die Literatur gehalten !! Wolfram Alpha liefert nämlich "BEF1": http://www.wolframalpha.com/input/?i=%28FA010000+base+16%29+mod+%2810001000000100001+base+2%29 Aber wo ist bloß mein Denkfehler? Was mache ich Falsch? Das kann doch unmöglich so schwer sein? _______________________________ Ergänzung: Verwende ich den folgenden Online CRC-Rechner, kommt das richtige raus unter folgender Eingabe: http://www.zorc.breitbandkatze.de/crc.html CRC-Order: 16 CRC-Polynom: 1021 Inital Value : FFFF Final XOR value: FFFF reverse data bytes :ON reverse CRC result before Final XOR: ON Eingabe : %FA%01
:
Bearbeitet durch User
Moe Espunkt schrieb: > Der Rest dieser Division müsste ja der CRC-Wert sein. Das ganze hab ich > mal in Wolfram Alpha eingegeben und es kommt nicht der gewünschte wert > von "B69F" raus!! Dabei habe ich mich ganz genau an die Literatur > gehalten !! Naja, fast... Du hast den Startwert 0xffff ignoriert (der bei HDLC üblich ist).
Georg G. schrieb: > Naja, fast... Du hast den Startwert 0xffff ignoriert (der bei HDLC > üblich ist). Wie lasse ich denn den Startwert 0xFFFF in die Rechnung mit einfließen? Weiß ehrlich gesag nicht, was ich mit diesem Startwert anfangen soll ...
Aus Wikipedia: Schieberegister := Startwert solange Bits im Datenstrom verbleiben: falls das am weitesten links stehende Bit vom Schieberegister ungleich dem nächsten Bit aus dem Datenstrom ist: Schieberegister := (Schieberegister linksschieben um 1, rechtes Bit 0) xor CRC-Polynom andernfalls: Schieberegister := Schieberegister linksschieben um 1, rechtes Bit 0 nächstes Bit im Datenstrom Schieberegister enthält das Ergebnis. Oft findet man andere Startwerte, etwa 1111…. Dies entspricht einer Polynomdivision, wenn die ersten n Bits des Datenstroms invertiert werden. Ende Wikipedia Sieh dir mal die CRC-Lib aus dem Atmel Studio an. Wenn CRC Erzeugung oder Check schnell gehen muss, macht man das mit Tabellen. Beispiel (mit falscher und deshalb gekürzter Tabelle). crc wird vor dem ersten Aufruf mit dem Startwert initialisiert. Funktion wird für jedes Byte des Datenstromes aufgerufen. crc enthält den zu übertragenden CRC-Wert. static void calc_crc(WORD *crc, BYTE c) { static const WORD Crc_table[] = { 0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38, ... 0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7, 0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff }; *crc = (*crc << 8) ^ Crc_table[(*crc >> 8) ^ c]; }
:
Bearbeitet durch User
$ ./pycrc.py --model x-25 --check-hexstring="FA01" 0x9fb6 bzw. b69f mit einem Byteswapper.... mit pycrc < 3 Minuten gebraucht ;-)
Hallo Tiramisu, vielen Dank für deine sehr hilfreiche Antwort. Ich habe das jetzt ebenfalls mit Python (Pycrc) gemacht. Als Ergebnis erhalte ich jedoch folgendes: C:\Python27>python pycrc.py --model x-25 --check-string="FA01" 0x6bf1 Irgendwie schon kurios oder? Eine Vermutung voran es liegen könnte? Ich überlege langsam einfach die CRC-Berechnung selber zu programmieren in dem ich einfach ein Schieberegister mit XOR-Verknüpfungen realisiere. Kann ja "eigentlich" nicht so schwer sein den CRC-Code zu implementieren ... Geht wahrscheinlich schneller als, wenn ich mich jetzt in andere Codes einarbeite.
:
Bearbeitet durch User
Wer lesen kann ist klar im Vorteil : es heißt "HEXSTRING" und nicht "STRING" ! also : C:\Python27>python pycrc.py --model x-25 --check-hexstring="FA01" 0x9fb6
:
Bearbeitet durch User
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.