在Python 3中将整数的字符串表示编码为Base64

19

我正在尝试将一个整数编码为base64,我的做法是:

foo = 1
base64.b64encode(bytes(foo))

预期输出:'MQ=='

给出的输出:b'AA=='

我做错了什么?

编辑:在Python 2.7.2中可以正常工作。


1
嗯...你用的是哪个版本的Python?当我执行base64.b64encode(bytes(1))或foo=1;base64.b64encode(bytes(foo))时,我得到的是'MQ=='。另外,你在哪里运行这个程序? - Foon
1
当我运行你的代码时,输出结果符合预期。你是否在其他地方重新定义了foo?尝试使用base64.b64encode(b'1')。 - Samy Arous
1
确认:在Python 3.1.2中,它打印 b'AA=='。问题不在于 b64encode,而是 bytes()。在Python3中,bytes(1) 返回 b'00' - Robᵩ
在Python3中,bytes()函数可以用作类型转换吗? - fj123x
2
请注意:这绝对不是重复内容。以下回答都不正确。请查看评论。 - Erik Aronesty
显示剩余4条评论
2个回答

16
如果您使用整数N初始化bytes(N),它将为您提供长度为N且初始化为空字节的字节:
>>> bytes(10)
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

你需要的是字符串"1";因此,请使用以下方法将其编码为字节:
>>> "1".encode()
b'1'

现在,base64将给你b'MQ=='

>>> import base64
>>> base64.b64encode("1".encode())
b'MQ=='

6
base64.b64encode(i.to_bytes(ceil(i.bit_length()/8),'big'))将整数 i 转换为字节类型,长度为 ceil(i.bit_length()/8),然后使用 base64 编码进行加密。 - Erik Aronesty

6

试试这个:

foo = 1
base64.b64encode(bytes([foo]))

或者

foo = 1
base64.b64encode(bytes(str(foo), 'ascii'))
# Or, roughly equivalently:
base64.b64encode(str(foo).encode('ascii'))

第一个例子编码了1字节整数1。第二个例子编码了1字节字符串'1'

这里返回的是 AQ== 而不是 MQ== - fj123x
第二个例子返回 MQ== - Robᵩ
4
对于想要编码整数但输出不符合预期的其他人:这个方法可以使用,但编码后的字符串可能比实际需要的长度长得多。这是因为将数字转换为字符串时,只使用了输入空间的一小部分,但b64encode不知道这一点(例如,它不知道永远不会有一个字母)。我认为最好使用“struct”模块进行编码,使用“b64encode(pack('<Q', foo).rstrip('\x00') or '\x00').rstrip('=')”这条语句,可以为大整数提供更短的编码字符串。 - Mark
6
这是实际的答案:base64.b64encode(i.to_bytes(ceil(i.bit_length()/8),'big'))翻译:该代码将整数i转换为字节数组,然后使用Base64编码对其进行编码,并返回编码结果。其中,ceil(i.bit_length()/8)用于计算字节数组的长度,'big'指定了字节序。 - Erik Aronesty
1
使用base64.b64encode(i.to_bytes((i.bit_length()+8)//8,'big',signed=True))来正确地将有符号数转换为Base64编码。使用int.from_bytes(base64.b64decode(z),'big',signed=True)来解码有符号数。(我改用了+8...//8而不是ceil...这样可以少用一个库,并且它会给你需要的额外位数以表示符号) - Erik Aronesty
显示剩余4条评论

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