en Python, de longs entiers ont une précision illimitée. Je voudrais écrire un entier de 16 octets (128 bits) à un fichier. Quelques éclaircissements ici: J'écris à un dossier qui va être lu dans des programmes non python, alors le cornichon est sorti. Les 128 bits sont utilisés. P> struct code> de la bibliothèque standard ne prend en charge que 8 entiers d'octets.
Array code> a la même limitation. Y a-t-il un moyen de le faire sans masquer et déplacer chaque entier? P>
9 Réponses :
Vous pouvez coraller l'objet à binaire, utilisez des tampons de protocole (je ne sais pas s'ils vous permettent de sérialiser des entiers de précision illimités cependant) ou de BSON si vous ne souhaitez pas écrire de code. P>
Mais écrire une fonction qui décharge 16 entiers d'octets en déplaçant qu'il ne faut pas être si difficile à faire si ce n'est pas le temps critique. P>
Deux solutions possibles: p>
Just Pickle Votre long entiers. Cela écrira l'entier dans un format spécial qui lui permet d'être lu à nouveau, si c'est tout ce que vous voulez. P> li>
Utilisez le deuxième extrait de code dans Cette réponse Pour convertir le long Int à une grosse chaîne Endian (qui peut être facilement changé en peu d'Endian si vous préférez) et écrivez cette chaîne à votre dossier. p> li> ol>
Le problème est que la représentation interne des BIGINTS n'inclut pas directement les données binaires que vous demandez. P>
Cela peut ne pas éviter le "masque et déplacer chaque integer" exigence. Je ne suis pas sûr d'éviter les moyens de masque et de décalage dans le contexte des valeurs longues Python.
Les octets sont ceux-ci: p> Vous pouvez alors emballer cette liste d'octets en utilisant structure.pack ("16b", octets) code> < / p> p>
"invalide"? Pourriez-vous être plus précis afin que je puisse le réparer?
Il y a une certaine confusion avec les noms de variables ( n code> vs. code> long_int code>). En outre, vous devez probablement utiliser
n // = 256 code> ou
n >> = 8 code> ou
n, b = divmod (n, 256) code> de
n / = 256 code> pour empêcher une boucle (presque) infinie dans Python 3 (ou lorsqu'un flotteur est passé).
@Apalala, @sven Marnach. Merci.
Cela peut probablement sembler plus agréable avec long_int, b = divmod (long_int, 256) code> :)
Je pense que pour les entiers non signés (et ignorer l'endansning) quelque chose comme peut techniquement satisfer aux exigences de la production spécifique non python, sans utiliser un masque explicite et (je suppose ) n'utilise aucun modules non standard. Pas particulièrement élégant, cependant. P> p>
Cela échoue à une entrée négative: heex (x) code> retourne
-0x123 code> par exemple.
@Score_under: La toute première phrase indique "pour les entiers non signés".
the PYPI Bitarray module en combinaison avec la corbeille bin () Code> La fonction semble être une bonne combinaison pour une solution simple et flexible.
bytes = bitarray(bin(my_long)[2:]).tobytes()
Fais attention! bin () code> produit quelque chose comme
0b0101110 code>, vous devez donc couper le préfixe
0b code>.
Vous voulez aussi Tobytes () code> pas
tostring () code>.
Pourquoi ne pas utiliser la structure avec le type em> disigne em> disigne deux fois?
import struct some_file.write(struct.pack("QQ", var/(2**64), var%(2**64)))
Cela peut être un peu tardif, mais je ne vois pas pourquoi vous ne pouvez pas utiliser STRIT:
bigint = 0xFEDCBA9876543210FEDCBA9876543210L print bigint,hex(bigint).upper() cbi = struct.pack("!QQ",bigint&0xFFFFFFFFFFFFFFFF,(bigint>>64)&0xFFFFFFFFFFFFFFFF) print len(cbi)
avec Python 3.2 et plus tard, vous pouvez utiliser int.to_bytes code> et
int.from_bytes code>: https://docs.python.org/3/library/sttypes.html#int.to_bytes p>
Basé sur la réponse de @ DSM et supporter des entiers négatifs et des tailles variées d'octets, j'ai créé l'extrait amélioré suivant:
def to_bytes(num, size): x = num if num >= 0 else 256**size + num h = hex(x)[2:].rstrip("L") return binascii.unhexlify("0"*((2*size)-len(h))+h)
On dirait qu'il l'a déjà fait - STRIT de la bibliothèque standard ne supporte que 8 entiers d'octets. I>
Avez-vous besoin de l'ensemble de la plage de 128 bits ou des 64 bits inférieurs, avez-vous besoin d'entiers signés?
duplicaté possible de Y a-t-il un moyen plus rapide de convertir un grand entier arbitraire à une grande séquence d'Endian d'octets?