Hallo zusammen,
ich habe hier meinen CRC Algorithmus (den ich aus C++ code übernommen habe). Jetzt habe ich ein Problem, und zwar wenn ich bestimmte strings übergebe (z.B. "bone_l_upperarm") bekomme ich von hex() eine Ziffer zu wenig zurück.
Für "bone_l_upperarm" bekomme ich "0x72c896bL" (das L sagt ja "long int"). Wenn ich aber den CRC durch ein anderes Programm berechnen lasse (das aber leider für meine Zwecke zu ineffizient ist) bekomme ich "0x072c896b". Die 0 direkt nach dem 0x fällt also weg.
Hier ist das Modul, die Funktion, über die ich rede ist "crc(string)".
https://github.com/Schlechtwetterfront/ ... sh2_crc.py
Passiert das nur weil die Null nach dem 0x nicht gebraucht wird, oder sowas ähnliches?
hex() verliert eine Null
@Ande: Genau deswegen. Woher sollte Python denn auch wissen wie viele führende Nullen ausgegeben werden sollen, falls überhaupt. Die Operationen die dort auf der Zeichenkettendarstellung die `hex()` liefert durchgeführt werden, sind aber sowieso keine gute Idee. Auf das Format sollte man sich IMHO nicht verlassen. Wenn meine Hexdarstellung haben möchte, dann sollte man Zeichenkettenformatierung verwenden. Dann bekommt man nur die Hexziffern und kann auch gleich mit angeben wie viele es sein sollen und das links mit 0en aufgefüllt werden soll.
Die leicht gruselige `strcrc()`/`hextranslate()` Kombination sollte man mit dem `binascii`-Modul lösen. Oder noch besser: die CRC-Funktion eine *Zahl* zurückgeben lassen, und die mit dem `struct`-Modul oder `ctypes` in eine Zeichenkette mit den Bytewerten umwandeln.
Die `unsigned()`-Funktion hat einen unpassenden Namen und auf jeden Fall eine irreführende Dokumentation. Was da passiert hat absolut gar nichts mit dem Vorzeichen der Zahl zu tun, sondern ausschliesslich wie viele Bits verwendet werden.
Die leicht gruselige `strcrc()`/`hextranslate()` Kombination sollte man mit dem `binascii`-Modul lösen. Oder noch besser: die CRC-Funktion eine *Zahl* zurückgeben lassen, und die mit dem `struct`-Modul oder `ctypes` in eine Zeichenkette mit den Bytewerten umwandeln.
Die `unsigned()`-Funktion hat einen unpassenden Namen und auf jeden Fall eine irreführende Dokumentation. Was da passiert hat absolut gar nichts mit dem Vorzeichen der Zahl zu tun, sondern ausschliesslich wie viele Bits verwendet werden.
So,
1. String Formatierung wäre dann:
2. Mit binascii statt hextranslate wäre das
, aber wie würde ich deine zweite Methode mit Zahl und struct genau umsetzen?
3. Das stimmt, was wäre denn ein besserer Name/Dokumentation? Sowas wie 'Simulate unsigned behavior by ... not using a bit for the sign'?
1. String Formatierung wäre dann:
Code: Alles auswählen
crc_string = '{0:08X}'.format(crc-number)
Code: Alles auswählen
binascii.unhexlify(crc_string)
3. Das stimmt, was wäre denn ein besserer Name/Dokumentation? Sowas wie 'Simulate unsigned behavior by ... not using a bit for the sign'?
@Ande: Deine »remove_sign_bit«-Funktion gibt die unteren 32-bit zurück, nicht mehr und nicht weniger. Der Name »remove_sign_bit« ist daher noch irreführender, zumal es gar kein Vorzeichen-Bit bei int-Zahlen gibt.
Mit struct sieht »strcrc« so aus:
Mit struct sieht »strcrc« so aus:
Code: Alles auswählen
def strcrc(string):
'''Calculate the Zero CRC and return it in a structure
usable in .msh files.'''
return struct.pack('<I',crc2(string))