170 votes

convertir une chaîne d'octets en int (python)

Comment puis-je convertir une chaîne d'octets dans un int en python?

Dire comme ceci: 'y\xcc\xa6\xbb'

Je suis venu avec un astucieux/stupide façon de le faire:

sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))

Je sais qu'il y a quelque chose builtin ou de la bibliothèque standard, qui est plus simplement...

Ceci est différent de la conversion d'une chaîne de chiffres hexadécimaux, pour lequel vous pouvez utiliser int(xxx, 16), mais à la place je veux convertir une chaîne de réelles valeurs d'octets.

Mise à JOUR:

J'aime bien James répondre un peu mieux car il ne faut pas l'importation d'un autre module, mais de Greg méthode est plus rapide:

>>> from timeit import Timer
>>> Timer('struct.unpack("<L", "y\xcc\xa6\xbb")[0]', 'import struct').timeit()
0.36242198944091797
>>> Timer("int('y\xcc\xa6\xbb'.encode('hex'), 16)").timeit()
1.1432669162750244

Mon hacky méthode:

>>> Timer("sum(ord(c) << (i * 8) for i, c in enumerate('y\xcc\xa6\xbb'[::-1]))").timeit()
2.8819329738616943

MISE À JOUR:

Quelqu'un a demandé dans les commentaires, quel est le problème avec l'importation d'un autre module. Ainsi, l'importation d'un module n'est pas forcément bon marché, prendre un coup d'oeil:

>>> Timer("""import struct\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""").timeit()
0.98822188377380371

Y compris le coût de l'importation du module nie presque la totalité de l'avantage que présente cette méthode. Je crois que ce ne comprennent pas les frais d'importation en une seule fois pour l'ensemble de l'indice de référence exécuter; regardez ce qui se passe quand je le forcer à recharger à chaque fois:

>>> Timer("""reload(struct)\nstruct.unpack(">L", "y\xcc\xa6\xbb")[0]""", 'import struct').timeit()
68.474128007888794

Inutile de dire que, si vous faites beaucoup de l'exécution de cette méthode par une importation que cela devient proportionnellement moins d'un problème. C'est aussi probablement le coût d'e/s plutôt que de cpu de sorte qu'il peut dépendre de la capacité et des caractéristiques de la charge de la machine.

357voto

Mechanical snail Points 8589

Dans Python 3.2 et versions ultérieures, utilisez

 >>> int.from_bytes(b'y\xcc\xa6\xbb', byteorder='big')
2043455163
 

ou

 >>> int.from_bytes(b'y\xcc\xa6\xbb', byteorder='little')
3148270713
 

en fonction de la finalité de votre chaîne d'octets.

Cela fonctionne également pour les entiers bytestring de longueur arbitraire et pour les entiers signés au complément à deux en spécifiant signed=True . Voir la documentation pour from_bytes .

112voto

Greg Hewgill Points 356191

Vous pouvez également utiliser le module struct pour faire ceci:

 >>> struct.unpack("<L", "y\xcc\xa6\xbb")[0]
3148270713L
 

68voto

James Antill Points 1676

Comme Greg l'a dit, vous pouvez utiliser struct si vous utilisez des valeurs binaires, mais si vous avez juste un "nombre hexadécimal" mais au format octet, vous voudrez peut-être simplement le convertir comme ceci:

 s = 'y\xcc\xa6\xbb'
num = int(s.encode('hex'), 16)
 

... c'est pareil que:

 num = struct.unpack(">L", s)[0]
 

... sauf que ça fonctionnera pour n'importe quel nombre d'octets.

8voto

Jrm Points 31

J'utilise la fonction suivante pour convertir des données entre int, hex et octets.

 def bytes2int(str):
 return int(str.encode('hex'), 16)

def bytes2hex(str):
 return '0x'+str.encode('hex')

def int2bytes(i):
 h = int2hex(i)
 return hex2bytes(h)

def int2hex(i):
 return hex(i)

def hex2int(h):
 if len(h) > 1 and h[0:2] == '0x':
  h = h[2:]

 if len(h) % 2:
  h = "0" + h

 return int(h, 16)

def hex2bytes(h):
 if len(h) > 1 and h[0:2] == '0x':
  h = h[2:]

 if len(h) % 2:
  h = "0" + h

 return h.decode('hex')
 

Source: http://opentechnotes.blogspot.com.au/2014/04/convert-values-to-from-integer-hex.html

6voto

Rafał Dowgird Points 16600
 import array
integerValue = array.array("I", 'y\xcc\xa6\xbb')[0]
 

Attention: ce qui précède est fortement spécifique à la plateforme. Le spécificateur "I" et la finalité de la conversion chaîne-> int dépendent de votre implémentation Python. Mais si vous voulez convertir plusieurs entiers / chaînes à la fois, le module tableau le fait rapidement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X