Seite 1 von 1

hex() verliert eine Null

Verfasst: Samstag 9. November 2013, 14:58
von Ande
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?

Re: hex() verliert eine Null

Verfasst: Samstag 9. November 2013, 15:26
von 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.

Re: hex() verliert eine Null

Verfasst: Sonntag 10. November 2013, 04:15
von Ande
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'?

Re: hex() verliert eine Null

Verfasst: Sonntag 10. November 2013, 10:23
von Sirius3
@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))