How do I write a long integer as binary in Python?

后端 未结 9 1213
梦谈多话
梦谈多话 2021-01-12 06:20

In Python, long integers have unlimited precision. I would like to write a 16 byte (128 bit) integer to a file. struct from the standard library supports only u

相关标签:
9条回答
  • This may not avoid the "mask and shift each integer" requirement. I'm not sure that avoiding mask and shift means in the context of Python long values.

    The bytes are these:

    def bytes( long_int ):
        bytes = []
        while long_int != 0:
            b = long_int%256
            bytes.insert( 0, b )
            long_int //= 256
        return bytes
    

    You can then pack this list of bytes using struct.pack( '16b', bytes )

    0 讨论(0)
  • 2021-01-12 06:42

    I think for unsigned integers (and ignoring endianness) something like

    import binascii
    
    def binify(x):
        h = hex(x)[2:].rstrip('L')
        return binascii.unhexlify('0'*(32-len(h))+h)
    
    >>> for i in 0, 1, 2**128-1:
    ...     print i, repr(binify(i))
    ... 
    0 '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    1 '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
    340282366920938463463374607431768211455 '\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff'
    

    might technically satisfy the requirements of having non-Python-specific output, not using an explicit mask, and (I assume) not using any non-standard modules. Not particularly elegant, though.

    0 讨论(0)
  • 2021-01-12 06:43

    Why not use struct with the unsigned long long type twice?

    import struct
    some_file.write(struct.pack("QQ", var/(2**64), var%(2**64)))
    

    That's documented here (scroll down to get the table with Q): http://docs.python.org/library/struct.html

    0 讨论(0)
  • 2021-01-12 06:43

    Based on @DSM's answer, and to support negative integers and varying byte sizes, I've created the following improved snippet:

    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)
    

    This will properly handle negative integers and let the user set the number of bytes

    0 讨论(0)
  • 2021-01-12 06:51

    With Python 3.2 and later, you can use int.to_bytes and int.from_bytes: https://docs.python.org/3/library/stdtypes.html#int.to_bytes

    0 讨论(0)
  • 2021-01-12 06:58

    Two possible solutions:

    1. Just pickle your long integer. This will write the integer in a special format which allows it to be read again, if this is all you want.

    2. Use the second code snippet in this answer to convert the long int to a big endian string (which can be easily changed to little endian if you prefer), and write this string to your file.

    The problem is that the internal representation of bigints does not directly include the binary data you ask for.

    0 讨论(0)
提交回复
热议问题