2009-03-30 9 views
3

Est-ce la meilleure façon de convertir un nombre Python en chaîne hexadécimale?Convertir un nombre en chaîne binaire

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

Parfois, il ne fonctionne pas et se plaint de chaîne de longueur Odd quand vous 1234567890.

Précision:

je vais d'int à six pans.

Aussi, j'ai besoin qu'il soit échappé.

IE: 1234567890 -> '\ x49 \ x96 \ x02 \ XD2' non '499602D2'

En outre, il doit être en mesure de prendre tout entier Python. C'EST À DIRE. quelque chose de plus grand qu'un Int.

Edit:

Voici la meilleure solution jusqu'à présent, j'ai bricolé à partir du poste de Paolo et Devin.

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

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

    return num.decode('hex') 
+1

Vous ne voulez pas convertir votre numéro à une chaîne hexadécimale du tout; vous voulez le convertir en une représentation binaire, ou base256. – Miles

+1

ack, "chaîne hexagonale" n'est vraiment pas le bon terme ici – hop

Répondre

6

Vous pouvez utiliser string formatting:

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

Ah sympa, maintenant comment l'obtenir afin qu'il produise '\ x75 \ xbc \ d1 \ x05'? – Unknown

+0

Vous pouvez utiliser minuscule x pour l'afficher en minuscules, je ne suis pas sûr de l'autre partie ... –

+0

Eh bien hex (nombre) [2: -1] .decode ('hex') fait cela, sauf qu'il gâche parfois . – Unknown

1

Parfois, il ne fonctionne pas et se plaint de chaîne de longueur Odd quand vous 1234567890.

Parce qu'il ne avoir un sens. Comment adaptez-vous 'AAB' dans un espace qui prend 2 ou 4 chiffres? Chaque octet est composé de deux caractères hexadécimaux. Lorsque vous avez un nombre impair de caractères hexadécimaux, le résultat souhaité est ambigu. Voulez-vous que ce soit l'équivalent de 0AAB ou AAB0? Si vous savez lequel vous voulez qu'il soit équivalent, ajoutez simplement ce caractère au bon endroit avant de le décoder.

à savoir (('0' + foo) if len(foo) % 2 else foo).decode('hex') où foo est une chaîne de la forme retournée par %x.

+0

Mauvaise façon. J'essaye de passer de l'int à l'hexagone, pas d'hex à int. – Unknown

+0

Désolé, j'ai mal lu et mépris des choses. La réponse est changée maintenant. –

+0

(Pour moi) il est plus logique d'ajouter un 0 de tête. Voir ma réponse. Le code peut facilement être ajusté si un espace de fin est préféré. – Stephan202

0

Comme mentionné Paolo, la mise en forme de chaîne est le chemin à parcourir. Notez que vous pouvez choisir entre les lettres majuscules et minuscules:

>>> 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' 

Notez que se sont échappés ajoute un zéro en cas d'un nombre impair de chiffres hexadécimaux. Cette solution fonctionne pour des chaînes de n'importe quelle longueur.

+0

Oui je sais mais j'ai besoin de le convertir en '\ x2a' ​​pas '2a' – Unknown

+0

Merci pour l'entrée. C'est presque le même que l'extrait que je viens de faire, mais je ne voulais pas qu'il soit échappé, donc je suppose qu'il faudrait un char() au lieu de '' .join ('\\ x') – Unknown

+0

Très bien, je – Stephan202

0

Si vous connaissez la durée de vos chaînes de sortie, le formatage des chaînes fonctionnera. Par exemple, pour obtenir des chaînes de quatre caractères, vous avez besoin d'une longueur formatée de huit:

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

Cela préfixer si votre numéro zéros ne pas « remplir » la chaîne.Par exemple, avec des chaînes de six caractères:

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

Edit:

Pour "détecter" la longueur des chaînes cibles, vous pouvez utiliser la fonction math.log:

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

Existe-t-il un moyen de détecter automatiquement la longueur en fonction de la taille du numéro – Unknown

+0

cela s'appelle un logarithme – hop

5

Je Je ne sais pas exactement ce que vous voulez, mais avez-vous regardé le module struct?

Étant donné

>>> hex(123456789) 
'0x75bcd15' 

Vous pouvez faire:

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

Notez que '\x5b' == '['.

En outre, vous pouvez inverser le boutisme:

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

Edit: Je ne sais pas ce que vous entendez par « plus grand qu'un long », depuis soupire après afaik en python sont sans bornes (sauf par la mémoire). Cependant, vous pouvez gérer des entiers plus grands en divisant et en concaténant. par exemple. donné:

>>> n = 123456789

la cible est:

>>> hex(n) 
'0x18ee90ff6c373e0ee4e3f0ad2L' 

Alors:

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

Voir qui s correspond au résultat de hex(n) ci-dessus:

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

J'ai besoin de quelque chose qui peut prendre un nombre plus grand qu'un Int ou un long. – Unknown

0

un des plus sûrs façon, pour un numéros rbitary, est d'utiliser le module « tableau » comme ceci:

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

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

hexStr = binArr.tostring() 
Questions connexes