Hallo liebe Gemeinde, ich hab schon oft Hilfe in dem Foruim gefunden und daher wollte ich euch mal fragen, ob ihr mir auch jetzt helfen könnt. :) Ich verscuhe vergebens zu erkennen, wie hier die Checksumme berechnet wird: Je Zeile steht ein anderer Block, letztes Byte ist Checksumme. 81 12 F0 1C 20 20 39 38 2E 31 1C 46 4D 32 2E 35 20 20 1C 42 81 12 F0 1C 20 20 39 39 2E 39 1C 46 4D 32 2E 34 20 20 1C 4A 81 12 F0 4D 44 52 20 4A 55 4D 50 46 4D 32 2E 31 20 20 1C 1F 81 12 F0 2A 54 4F 50 66 34 30 2A 46 4D 32 2E 33 20 20 1C 71 81 12 F0 41 4E 54 2E 54 48 55 45 46 4D 32 2E 32 20 20 1C 22 Die Daten oben werden auf der Leitung invertiert übertragen, also könnte die Checksumme auch aus dem gebildet werden: 7E ED F E3 DF DF C6 C7 D1 CE E3 B9 B2 CD D1 CA DF DF E3 BD 7E ED F E3 DF DF C6 C6 D1 C6 E3 B9 B2 CD D1 CB DF DF E3 B5 7E ED F B2 BB AD DF B5 AA B2 AF B9 B2 CD D1 CE DF DF E3 E0 7E ED F D5 AB B0 AF 99 CB CF D5 B9 B2 CD D1 CC DF DF E3 8E 7E ED F BE B1 AB D1 AB B7 AA BA B9 B2 CD D1 CD DF DF E3 DD Ich habe probiert die Byte zu addieren komme aber nicht auf die 42. Die ersten 3 Bytes sind Init Bytes, daher denke ich, sie gehören nicht mit zur Checksumme, weiß es aber nicht genau. Habe auch schon probiert, die nicht invertieren Bytes zu addieren und auf die Invertiere Checksumme zu kommen, nix hilft. Sieht einer das Verfahren? Was für Möglichkeiten sind denn gebräuchlich? Vielen Dank! Tobi
T-Snake schrieb:
> Sieht einer das Verfahren? Was für Möglichkeiten sind denn gebräuchlich?
Bei solchen zeilenweisen Checksummen wird auch gerne folgendes gemacht:
Alle Bytes miteinander ver-XODER-n
Du solltest dir auch mal das gesamte Protokoll durchschauen es könnte auch möglich sein das nur von den effektiven Daten die Checksumme gebildet wird. D.h. die Header und sonstige Befehle werden anderweitig interpretiert und nicht zur Checksummenbildung miteinbezogen. Also nur mal die versendeten Daten aufaddieren, gruß sw1ft
Die Checksumme scheint immer das "running xor" (wie von Karl Heinz vermutet) plus eins zu sein:
1 | #include <iostream> |
2 | |
3 | int main(int argc, char *argv[]) |
4 | { |
5 | int checksum = 0; |
6 | int data0[] = {0x81, 0x12, 0xF0, 0x1C, 0x20, 0x20, 0x39, 0x38, 0x2E, 0x31, 0x1C, 0x46, 0x4D, 0x32, 0x2E, 0x35, 0x20, 0x20, 0x1C}; |
7 | int data1[] = {0x81, 0x12, 0xF0, 0x1C, 0x20, 0x20, 0x39, 0x39, 0x2E, 0x39, 0x1C, 0x46, 0x4D, 0x32, 0x2E, 0x34, 0x20, 0x20, 0x1C}; |
8 | int data2[] = {0x81, 0x12, 0xF0, 0x4D, 0x44, 0x52, 0x20, 0x4A, 0x55, 0x4D, 0x50, 0x46, 0x4D, 0x32, 0x2E, 0x31, 0x20, 0x20, 0x1C}; |
9 | int data3[] = {0x81, 0x12, 0xF0, 0x2A, 0x54, 0x4F, 0x50, 0x66, 0x34, 0x30, 0x2A, 0x46, 0x4D, 0x32, 0x2E, 0x33, 0x20, 0x20, 0x1C}; |
10 | int data4[] = {0x81, 0x12, 0xF0, 0x41, 0x4E, 0x54, 0x2E, 0x54, 0x48, 0x55, 0x45, 0x46, 0x4D, 0x32, 0x2E, 0x32, 0x20, 0x20, 0x1C}; |
11 | for (int i=0; i<19; i++) { |
12 | checksum ^= data4[i]; |
13 | } |
14 | |
15 | std::cout << std::hex << checksum << std::endl; |
16 | |
17 | } |
Mirko
... ja, oder das XOR mit einem Startwert von 1 statt 0. Das wird besser hinkommen, wenn aus dem XOR mit Startwert 0 zufällig 0xFF rauskommt; plus 1 würde dann nur funktionieren, wenn man das Ergebnis wieder auf ein Byte beschneidet. Mit 1 als Startwert und zum Schluß keine 1 addieren passt es dann automatisch.
das sind aber zwei unterschiedliche Algorithmen die ihr da beschreibt ...
Ja, aber welcher der richtige ist, lässt sich aus den Beispielen wohl nicht entnehmen. Klaus hat recht, dass der start mit 1 sinnvoller ist, letztendlich muss T-Snake jetzt die Grenzfälle abtesten. Mirko
sorry, ich nehme das aber wieder zurück. Bei XOR ist 1 als Startwert Quark, wenn Mirkos Weg stimmt. Er addiert ja nicht immer 1, sondern wechselt letztlich das letzte Bit. Das war ein Schnellschuß von mir :-( Es bleibt aber dabei, daß man bei der Korrektur um 1 lt. Mirko einen Überlauf richtig behandeln muß.
Hallo, ich hatte erste das mit dem +1 am Ende umgesetzt, das führt ab und zu zum falschen Ergebnis, die Variante mit 1 als Start hingegen, gibt immer die richtige Checksumme aus. Ich weiß garnicht wie ich euch danken soll :)
Hallo, ich nochmal. Leider geht die CRC nicht immer. Ich habe einen Block, das Versagt das Verfahren: 55 0C 0A 00 00 FA FF FF FF FF FF FF FF 55 Mit den 1Start dann XOR kommt man auf 57
dann musst du halt mal eine ordentliche Tüte voll Testdaten liefern, bevor man sich ransetzen kann. Oder ist vielleicht der eine Datensatz falsch?
Wenn ich eine als CRC sende, geht der Befehl. Bei einer 57 geht er nicht. Das Problem ist, ich habe nur begrenzt Datensätze da. Es ist def. eine XOR Verbindung, nur irgendwo ist noch ein kleiner Fehler. Wenn die Variante oben geht, jedoch nur zu 50% muss man doch eigentlich den Fehler finden können. Ich schaue mal, ob ich noch mehr gültige Blöcke finde. Bier gibs, musst nur vorbei komm :P
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.