在Python中将整数以二进制形式写入文件

6

如何在Python 3中以二进制形式将整数写入文件?

例如,我想以二进制形式将6277101735386680763835789423176059013767194773182842284081写入文件,确保大小为24字节(无符号,仅使用正整数)。我该如何做?我尝试了以下方法:

struct.pack("i", 6277101735386680763835789423176059013767194773182842284081)

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

我尝试过使用其他格式(“l”,“Q”),但它们也会导致错误。
struct.error: argument out of range

如果我能将整数转换为24个字节,那么我就可以写入文件,因为我知道如何做到这一点。但是,我无法将整数转换为字节。
此外,我如何确保每个整数都恰好写入24个字节?我还会写入更小的数字(1000、2000、1598754、12),但这些数字也应该占用24个字节。
我之后如何从文件中再次读取整数?

http://code.activestate.com/recipes/576617-converting-arbitrary-size-python-integers-to-packe/ - Martijn Pieters
3个回答

15

使用Python 3,您可以执行以下操作:

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)

输出:

$ python3 tiny.py
6277101735386680763835789423176059013767194773182842284081

1
为什么您不需要指示应从文件中读取24个字节?byteorder="big"已经表示了这一点吗? - Dasherman
不,读取部分没有限制。文件内容将被转换为数字。如果您只想读取前24个字节,请用file.read()[:24]替换file.read()byteorder='big'是存储数字的约定,详情请参见http://en.wikipedia.org/wiki/Endianness。 - Anton Zuenko
"byteorder="big"究竟表示什么意思?" - Dasherman
移除“byteorder = big”参数会使脚本以“正常”的二进制格式写入文件吗?因为这正是我要寻找的(00000000=0,00000001=1,00000010=2,00000011=3等),或者“byteorder = big”已经自动实现了这一点? - Dasherman
字节序只是一种约定。每个8位字节都按照您所展示的方式存储,但是您非常长的整数中24个字节的顺序取决于您的“字节序”。只要您读写方式相同,选择大端或小端都无关紧要。 - Fred S
显示剩余2条评论

1
您可以使用以下代码提取最不重要的字节:

  x = value & 0xFF

而且你可以使用以下代码从数字中删除该字节:

  value = value >> 8

重复这个过程24次将给你字节。
您还可以通过取出更多的字节来加快此过程,例如使用
 x = value & 0xFFFFFFFF
 value = value >> 32

你每次处理4个字节。


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Joran Beasley

0

我最终使用了类似这样的东西:

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/

int(a, 16).to_bytes(len(a) // 2, byteorder='big') 中,我将字符串的长度除以2,因为256(一个字节信息的大小)等于 16 ** 2(两个十六进制数字的信息大小)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接