hex() verliert eine Null

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Ande
User
Beiträge: 24
Registriert: Donnerstag 24. März 2011, 18:36

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?
BlackJack

@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.
Benutzeravatar
Ande
User
Beiträge: 24
Registriert: Donnerstag 24. März 2011, 18:36

So,
1. String Formatierung wäre dann:

Code: Alles auswählen

crc_string = '{0:08X}'.format(crc-number)
2. Mit binascii statt hextranslate wäre das

Code: Alles auswählen

binascii.unhexlify(crc_string)
, 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'?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@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:

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))
Antworten