2009-03-30 17 views
3

Ist dies der beste Weg, um eine Python-Nummer in eine Hex-Zeichenfolge zu konvertieren?Zahl in binäre Zeichenfolge konvertieren

number = 123456789 
hex(number)[2:-1].decode('hex') 

Manchmal funktioniert es nicht und beschwert sich über Odd-Zeichenfolge, wenn Sie tun 1234567890

Klarstellung:

Ich gehe von int nach hex.

Auch ich brauche es zu entkommen.

IE: 1234567890 -> '\ x49 \ x96 \ x02 \ xd2' nicht '499602D2'

Auch er muss in der Lage sein, jeden Python integer zu nehmen. IE. etwas größer als ein Int.

Edit:

Hier ist die beste Lösung, bisher habe ich zusammengeschustert von Paolo und Devin Beitrag.

def hexify(num): 
    num = "%x" % num 

    if len(num) % 2: 
     num = '0'+num 

    return num.decode('hex') 
+1

Sie wollen nicht auf alle Ihre Zahl in einen Hex-String konvertieren; Sie möchten es in eine binäre Darstellung oder base256 konvertieren. – Miles

+1

ack, "hex string" ist wirklich nicht der richtige Begriff hier – hop

Antwort

6

können Sie string formatting verwenden:

>>> number = 123456789 
>>> hex = "%X" % number 
>>> hex 
'75BCD15' 
+0

Ah schön, wie bekomme ich es jetzt so wird es '\ x75 \ xbc \ d1 \ x05' ausgeben? – Unknown

+0

Sie können Kleinbuchstaben X verwenden, um es in Kleinbuchstaben anzuzeigen, ich bin mir nicht sicher über den anderen Teil ... –

+0

Nun hex (Nummer) [2: -1] .decode ('hex') macht, dass es manchmal vermasselt . – Unknown

1

Manchmal funktioniert es nicht und beschwert sich über Odd-Zeichenfolge, wenn Sie 1234567890.

tun, weil es nicht der Fall ist Sinn ergeben. Wie passt man "AAB" in einen Raum, der entweder 2 oder 4 Ziffern hat? Jedes Byte besteht aus zwei Hexadezimalzeichen. Wenn Sie eine ungerade Anzahl von Hex-Zeichen haben, ist das gewünschte Ergebnis nicht eindeutig. Möchten Sie, dass es 0AAB oder AAB0 entspricht? Wenn Sie wissen, mit welchem ​​Sie es vergleichen möchten, fügen Sie dieses Zeichen an die richtige Stelle hinzu, bevor Sie es dekodieren.

d.h. (('0' + foo) if len(foo) % 2 else foo).decode('hex') wo foo ein String in der Form von %x.

+0

Falscher Weg. Ich versuche von int nach hex zu wechseln, nicht von hex nach int. – Unknown

+0

Entschuldigung, ich habe beide Dinge falsch gelesen und falsch gelesen. Die Antwort ist jetzt geändert. –

+0

(Für mich) ist es sinnvoller, eine führende 0 hinzuzufügen. Siehe meine Antwort. Der Code kann leicht angepasst werden, wenn ein nachstehendes Leerzeichen bevorzugt wird. – Stephan202

0

Wie Paolo erwähnt, string Formatierung zurückgegeben wird, ist der Weg zu gehen. Beachten Sie, dass zwischen Groß- und Kleinbuchstaben wählen:

>>> hex = lambda n: '%X' % n 
>>> hex(42) 
'2A' 
>>> hex = lambda n: '%x' % n 
>>> hex(42) 
'2a' 
>>> def escaped(n): 
...  s = hex(n) 
...  if len(s) & 1: 
...   s = '0' + s 
...  return ''.join(chr(int(s[i:i + 2], 16)) for i in range(0, len(s), 2)) 
... 
>>> escaped(123) 
'{' 
>>> escaped(1234) 
'\x04\xd2' 
>>> escaped(12348767655764764654764445473245874398787989879879873) 
'!\x01^\xa4\xdf\xdd(l\x9c\x00\\\xfa*\xf3\xb4\xc4\x94\x98\xa9\x03x\xc1' 

Beachten Sie, dass fügt entkam eine führende Null bei einer ungeraden Anzahl von Hex-Ziffern. Diese Lösung funktioniert für Strings beliebiger Länge.

+0

Ja, ich weiß, aber ich brauche es in '\ x2a' ​​konvertieren nicht '2a' – Unknown

+0

Vielen Dank für die Eingabe. Es ist fast das gleiche wie das Snippet, das ich gerade gemacht habe, aber ich wollte nicht, dass es maskiert wird, also denke ich, dass es ein char() anstelle von '' .join ('\\ x ") benötigen würde – Unknown

+0

In Ordnung, ich änderte die return-Anweisung – Stephan202

0

Wenn Sie wissen, wie lange Ihre Ausgabezeichenfolgen sein sollten, funktioniert die Formatierung von Zeichenfolgen. Zum Beispiel können vier-Zeichenketten zu erhalten, müssen Sie eine formatierte Länge von acht:

>>> "{0:08x}".format(123456789).decode("hex") 
'\x07[\xcd\x15' 
>>> "{0:08x}".format(1234567890).decode("hex") 
'I\x96\x02\xd2' 

Dies wird Nullen voranstellen, wenn Ihre Nummer nicht „füllen“ die Zeichenfolge.Zum Beispiel mit sechs Zeichenketten:

>>> "{0:012x}".format(123456789).decode("hex") 
'\x00\x00\x07[\xcd\x15' 
>>> "{0:012x}".format(1234567890).decode("hex") 
'\x00\x00I\x96\x02\xd2' 

Edit:

zu "erkennen" die Länge der Ziel Strings, können Sie die math.log Funktion verwenden können:

>>> def int2str(n): 
     l = int(math.ceil(math.log(n, 256)/2) * 4) 
     return ("{0:0{1}x}").format(n, l).decode("hex") 

>>> int2str(123456789) 
'\x07[\xcd\x15' 
>>> int2str(1234567890) 
'I\x96\x02\xd2' 
+0

Gibt es eine Möglichkeit, die Länge automatisch anhand der Größe der Nummer zu erkennen? – Unknown

+0

es heißt ein Logarithmus – hop

5

I‘ bin mir nicht sicher was genau du willst, aber hast du dir das struct Modul angeschaut?

Bei

>>> hex(123456789) 
'0x75bcd15' 

Sie tun können:

>>> struct.pack('i', 123456789) 
'\x15\xcd[\x07' 

Beachten Sie, dass '\x5b' == '['.

Auch können Sie die endianness umkehren:

>>> struct.pack('>i', 123456789) 
'\x07[\xcd\x15' 

Edit: Ich bin nicht sicher, was Sie mit "größer als einem langen" bedeuten, da AFAIK longs in Python unbegrenzt ist (mit Ausnahme von Speichern). Sie können jedoch mit größeren Ganzzahlen umgehen, indem Sie sie teilen und verketten. z.B. gegeben:

>>> n = 123456789

das Ziel ist:

>>> hex(n) 
'0x18ee90ff6c373e0ee4e3f0ad2L' 

So:

>>> s = '' 
>>> while n >= 2**32: 
... n, r = divmod(n, 2**32) 
... s = struct.pack('>l', r) + s 
... 
>>> s = struct.pack('>l', n) + s 

Sehen Sie, dass s das Ergebnis hex(n) oben entspricht:

>>> s 
'\x00\x00\x00\x01\x8e\xe9\x0f\xf6\xc3s\xe0\xeeN?\n\xd2' 
+0

Ich brauche etwas, das eine Zahl größer als ein Int oder lang dauern kann. – Unknown

0

eine der sichersten Weg, für eine rbitary Zahlen, ist die ‚Array‘ Modul wie folgt zu verwenden:

from array import array 
binArr = array('B') 

while(data): 
    d = data & 0xFF 
    binArr.append(d) 
    data >>= 8 

hexStr = binArr.tostring() 
Verwandte Themen