Verständnis der Ergebnisse von CRC8 SAE J1850 (normal) vs. "Null"
Brauche ich eine Bestätigung, CRC8-SAE-J1850-Meldungen und deshalb ein Skript geschrieben, das liest Protokolle und Bedürfnisse zu berechnen, CRC8 (nicht NULL) von dort aus zu Ihnen passen mit der CRC8-Werte in der log und dann schauen, bei welchem Schritt der tool-Kette verursacht den ärger.
Wie auch immer, ich verbrachte einige Zeit mit der Suche in der Dokumentation, SO dass Beiträge und andere Völker sourcecode, aber ich möchte zu halten mit python einfacher für textprocessing und Schnittstellen zu meinen anderen tools.
Fand ich einige code auf sourceforge evansneath die Python-CRC-Implementierung, die schön gerade nach vorne und wollte zu geben, es zu gehen, aber ich dachte, es funktioniert nicht wie erwartet (vielleicht habe ich etwas völlig falsch verstanden, aber ich bin hier hängengeblieben):
def crc(msg, div, code='11111111'):
"""Cyclic Redundancy Check
Generates an error detecting code based on an inputted message and divisor in the form of a polynomial representation.
Arguments:
msg: The input message of which to generate the output code.
div: The divisor in polynomial form. For example, if the polynomial of x^3 + x + 1 is given, this should be represented as '1011' in the div argument.
code: This is an option argument where a previously generated code may be passed in. This can be used to check validity. If the inputted code produces an outputted code of all zeros, then the message has no errors.
Returns:
An error-detecting code generated by the message and the given divisor.
"""
msg = msg + code
msg = list (msg)
div = list (div)
for i in range (len (msg) - len (code)):
if msg[i] == '1':
for j in range (len (div)):
msg[i+j] = str ((int (msg[i+j])+int (div[j]))%2)
return ''.join (msg[-len (code):])
#Testing:
# Use a divisor that simulates: CRC8 SAE J1850 x^8+x^4+x^3+x^2+x^0
div = '100011101'#0x1D with leading 1 as given by polynomial
msg = '10101001' # 0xA9, just for a Test
print('Input message:', hex(int(msg,2)))
print('Polynomial:', hex(int(div,2)))
o = '11111111'
z = '00000000'
code = crc(msg, div, o)
print('CRC8 code:', hex(int(code,2)))
# Test for output code of '00000000' respectively '11111111' proving that the function worked correctly
print('Success:', crc(msg, div, code) == o)
Habe ich überprüft, die Ergebnisse mit diesem generator:
CRC-Generator das scheint der einzige zu sein, mit CRC8 SAE J1850 NULL und nicht-NULL.
Nun der spaßige Teil: für die ZERO-der obige code funktioniert es bestens.
Leider die CRC-codes, die ich von der software, die ich überprüfen möchten initialisiert und überprüft 0xFF ('11111111'), wo beide tools liefern komplett unterschiedliche Ergebnisse.
So weit hatte ich gar nicht in der Lage zu finden, einige off-by-one-Ausgabe (die ich würde haben, bewerteten die wahrscheinlichste Fall), oder eine mathematische Verknüpfung zwischen der Lösung berechnet, indem das obige Skript und die von der website.
Die website entspricht dem Ergebnis aus der software jedoch die python-Teil oben nicht.
Kann jemand mir eine Dokumentation, die ich verpasst haben könnte oder ist das ein anderes Problem?
Ich habe bereits überprüft für MSB/LSB-Probleme bei der Eingabe von Nachrichten auf der website und versucht, die Initialisierung mit 0xFE, wie einige andere code vorgeschlagen. Aber kein Erfolg... die Meisten Beispiele sind jedoch null-basiert und dort habe ich keine Probleme.
Bearbeiten:
Habe ich überprüft, die Berechnung und gingen durch ein Beispiel per hand als auch den Druck auf jeden einzelnen Schritt an und erreicht die gleiche. Mathematisch So scheint es richtig, aber was ist mit der SAE zu tun, andere als das Anhängen einer Zeile von '11111111' und dann XOR-ing bitweise, dann verschieben bis es ein führender wieder, XOR-ing etc... und spuckt den Rest aus? Es muss ein Problem des Verstehens auf meiner Seite.
Test 1 ---------------------------
Input message: 0xa9
Polynome: 0x11d
['1', '0', '1', '0', '1', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', 1']
/
['1', '0', '0', '0', '1', '1', '1', '0', '1']
=
current message: ['1', '0', '1', '0', '1', '0', '0', '1', '1', '1', '1', '1', '1 ', '1', '1', '1']
shift 0 Bits
1 XOR 1 = 0
0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 0 = 0
1 XOR 1 = 0
0 XOR 1 = 1
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
current message: ['0', '0', '1', '0', '0', '1', '1', '1', '0', '1', '1', '1', '1 ', '1', '1', '1']
shift 2 Bits
1 XOR 1 = 0
0 XOR 0 = 0
0 XOR 0 = 0
1 XOR 0 = 1
1 XOR 1 = 0
1 XOR 1 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
current message: ['0', '0', '0', '0', '0', '1', '0', '0', '1', '1', '0', '1', '1 ', '1', '1', '1']
shift 5 Bits
1 XOR 1 = 0
0 XOR 0 = 0
0 XOR 0 = 0
1 XOR 0 = 1
1 XOR 1 = 0
0 XOR 1 = 1
1 XOR 1 = 0
1 XOR 0 = 1
1 XOR 1 = 0
CRC8 code: 0xab
Reverse Calculation: Check
['1', '0', '1', '0', '1', '0', '0', '1', '1', '0', '1', '0', '1', '0', '1', '1']
/
['1', '0', '0', '0', '1', '1', '1', '0', '1']
=
current message: ['1', '0', '1', '0', '1', '0', '0', '1', '1', '0', '1', '0', '1', '0', '1', '1']
shift 0 Bits
1 XOR 1 = 0
0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 0 = 0
1 XOR 1 = 0
0 XOR 1 = 1
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
current message: ['0', '0', '1', '0', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '1', '1']
shift 2 Bits
1 XOR 1 = 0
0 XOR 0 = 0
0 XOR 0 = 0
1 XOR 0 = 1
1 XOR 1 = 0
1 XOR 1 = 0
0 XOR 1 = 1
0 XOR 0 = 0
1 XOR 1 = 0
current message: ['0', '0', '0', '0', '0', '1', '0', '0', '1', '0', '0', '0', '1', '0', '1', '1']
shift 5 Bits
1 XOR 1 = 0
0 XOR 0 = 0
0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 1 = 1
0 XOR 1 = 1
0 XOR 1 = 1
1 XOR 0 = 1
0 XOR 1 = 1
CRC correct: True
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dass CRC ist normalerweise definiert mit folgenden Parametern:
crcgen nehmen wird, und erzeugen von C-code zur Berechnung der CRC. Sie können ganz einfach übersetzen, die zu Python, wenn Sie mögen. Hier ist die bit-Weise routine in C von crcgen:
Den "ZERO" - version aufgeführt, die auf der verknüpften CRC-Rechner-Seite hat diese Parameter einfach ändern Sie die anfangs-und xorout Werte auf null:
Hier ist die bit-Weise routine in C von crcgen für:
init
Wert in der Spezifikation. Der erste SFB, der Sie ernähren würde, um eine typische CRC-Funktion den CRC einer leeren Zeichenfolge, dieinit ^ xorout
. Das ist nichtinit
es sei dennxorout
null ist.width=8 poly=0x1d init=0xff refin=false refout=false xorout=0xff check=0x4b name="CRC-8/SAE-J1850"
auf reveng.sourceforge.net/crc-catalogue/1-15.htm#crc.cat-bits.8, die übrigens links zu einem Ihrer Projekte. Ich habe Sie noch nicht in der Lage gewesen, einen Grund zu finden, warum diese Methode liefert das gleiche Ergebnis für die init xorout = 0x00 aber unterscheidet sich für init, xorout = 0xFF als die website ...Ich es gelöst.
Es wird nie erwähnt, dass für die SAE-J1850 die Eingabe wird XORed mit 0xFF. Obwohl der C-code Mark Adler bereitgestellt ist genau festgelegt, dass in
crc ^= 0xff;
aber es hat nicht mir helfen zu verstehen, was mein problem war.War es nicht ein Fehler, mein code war richtig, aber es war der Räumlichkeiten habe ich angenommen.
Dies ist der Grund, warum der C-Code hat mir nicht geholfen das Problem zu lösen, weil ich das nie verstanden, das war das problem in den ersten Platz.
Den korrigierten code für SAE J1850 Berechnung (mit XORin 0xFF, XORout 0xFF, nicht reflektiert, nicht Umgekehrt, Polynom 0x1D) Bit-für-Bit ist wie folgt.
Credits für den code, bleibt mit evensneath auf github ich lediglich geändert, der Eingang.
Testcases aus der Frage, können übernommen werden. rufen Sie einmal zu generieren CRC, rufen Sie wieder mit msg + generierten crc überprüfen.
Gut Quelle: http://reveng.sourceforge.net/crc-catalogue/1-15.htm#crc.cat-bits.8
init
) und was zu den exklusiv-oder-Ausgang mit (xorout
).xorout
ist erforderlich, wenn die Verkettung in Ordnung zu rekonstruieren, die den Inhalt des Registers aus dem letzten Lauf.