Dasherman
Dasherman

Reputation: 383

Writing integers in binary to file in python

How can I write integers to a file in binary in Python 3?

For example, I want to write 6277101735386680763835789423176059013767194773182842284081 to a file in binary in exactly 24 bytes (unsigned, I will only be working with positive integers). How can I do this? I tried the following:

struct.pack("i", 6277101735386680763835789423176059013767194773182842284081)

This results in

ValueError: cannot fit 'int' into an index-sized integer

I have tried the same with some other formats ("l", "Q"), but those also result in errors:

struct.error: argument out of range

If I could convert the integer to exactly 24 bytes, I would be able to write to the file, since I know how to do that. However, I can't seem to convert the integers into bytes.

Also, how do I make sure that exactly 24 bytes are written per integer? I will also be writing smaller numbers (1000, 2000, 1598754, 12), however those should also take 24 bytes.

And how can I read the integers again from the file afterwards?

Upvotes: 8

Views: 26929

Answers (3)

Mathieu CAROFF
Mathieu CAROFF

Reputation: 1462

I ended up using something like this:

def hexstring2bytes(a):
    return int(a, 16).to_bytes(len(a) // 2, byteorder='big')

hexwasm = "0061736d0100000001080260017c0060000002070101690166000003020101070501016500010a3801360044000000000000f03f4400000000000020409f440000000000c05840440000000000c05840a2a34400000000003c9140a2a310000b"

from pathlib import Path

Path("compute_pi.wasm").write_bytes(hexstring2bytes(hexwasm))

# the load that file into https://webassembly.github.io/wabt/demo/wasm2wat/

In int(a, 16).to_bytes(len(a) // 2, byteorder='big'), I divide the length of the string by 2 because 256 (the size of the information of a byte) is 16 ** 2 (the size of the information of two hexadecimal digits),

Upvotes: 0

Anton Zuenko
Anton Zuenko

Reputation: 751

With Python 3 you can do the following:

i = 6277101735386680763835789423176059013767194773182842284081
with open('out.bin', 'wb') as file:
    file.write((i).to_bytes(24, byteorder='big', signed=False))

with open('out.bin', 'rb') as file:
    j = int.from_bytes(file.read(), byteorder='big')

print(j)

Output:

$ python3 tiny.py
6277101735386680763835789423176059013767194773182842284081

Upvotes: 17

6502
6502

Reputation: 114461

You can extract the least significant byte with

  x = value & 0xFF

and you can remove that byte from the number with

  value = value >> 8

Repeating this procedure 24 times will give you the bytes.

You can also speed up this process by taking out more bytes, for example with

 x = value & 0xFFFFFFFF
 value = value >> 32

you're processing 4 bytes at a time.

Upvotes: 1

Related Questions