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.