"0110100001101001"
)转换成字节数组(同样的例子,b"hi"
)。我尝试了这个:
bytes([int(i) for i in "0110100001101001"])
但我得到了:
b'\x00\x01\x01\x00\x01' #... and so on
在Python 3中,这应该如何正确地实现?
"0110100001101001"
)转换成字节数组(同样的例子,b"hi"
)。bytes([int(i) for i in "0110100001101001"])
但我得到了:
b'\x00\x01\x01\x00\x01' #... and so on
在Python 3中,这应该如何正确地实现?
这是按照 Patrick 所提到的第一种方式进行操作的示例:将比特串转换为整数,并每次取 8 位。自然的方法是以相反的顺序生成字节。为了将字节恢复到正确的顺序,我使用 b[::-1]
对 bytearray 进行扩展切片符号,步长为 -1。
def bitstring_to_bytes(s):
v = int(s, 2)
b = bytearray()
while v:
b.append(v & 0xff)
v >>= 8
return bytes(b[::-1])
s = "0110100001101001"
print(bitstring_to_bytes(s))
显然,Patrick的第二种方式更紧凑。 :)
然而,在Python 3中有一种更好的方法:使用int.to_bytes方法:
def bitstring_to_bytes(s):
return int(s, 2).to_bytes((len(s) + 7) // 8, byteorder='big')
如果 len(s)
被保证是 8 的倍数,则 .to_bytes
的第一个参数可以简化:
return int(s, 2).to_bytes(len(s) // 8, byteorder='big')
如果len(s)
不是8的倍数,这将引发OverflowError
,某些情况下可能会希望如此。
另一种选择是使用双重否定执行上取整除法。对于整数a和b,可以使用//
进行下取整除法。
n = a // b
给出整数n使得
n <= a/b < n + 1
例如,
47 // 10
给出4,以及
-47 // 10
给出-5。因此
-(-47 // 10)
给出5,有效执行取整除法。
因此,在 bitstring_to_bytes
中,我们可以这样做:
return int(s, 2).to_bytes(-(-len(s) // 8), byteorder='big')
然而,很少有人熟悉这种高效且紧凑的习惯用语,因此它通常被认为比较难读。
return int(s, 2).to_bytes((len(s) + 7) // 8, byteorder='big')
-(-len(s) // 8)
。 - PM 2Ring你需要将它转换为 int 并每次取 8 个 bit,或将其切成 8 个字节长度的字符串,然后将每个字节字符串转换为 int。在 Python 3 中,如 PM 2Ring 和 J.F Sebastian 的答案所示,int
的 to_bytes()
方法可以非常高效地实现第一种方法。这在 Python 2 中不可用,所以对于那些被困在 Python 2 中的人来说,第二种方法可能更加高效。以下是一个示例:
>>> s = "0110100001101001"
>>> bytes(int(s[i : i + 8], 2) for i in range(0, len(s), 8))
b'hi'
>>> list(range(0, 50, 8))
[0, 8, 16, 24, 32, 40, 48]
>>> list(range(0, len(s), 8))
[0, 8]
list()
来展示从 Python 3 的 range 迭代器中检索的值。)>>> [s[i : i + 8] for i in range(0, len(s), 8)]
['01101000', '01101001']
然后我们可以将它们转换为二进制整数:
>>> list(int(s[i : i + 8], 2) for i in range(0, len(s), 8))
[104, 105]
bytes()
将整个内容封装起来以得到答案。>>> bytes(int(s[i : i + 8], 2) for i in range(0, len(s), 8))
b'hi'
>>> zero_one_string = "0110100001101001"
>>> int(zero_one_string, 2).to_bytes((len(zero_one_string) + 7) // 8, 'big')
b'hi'
它返回一个不可变的字节序列 bytes
对象。如果你想获得一个可变的字节序列 bytearray
,那么只需调用 bytearray(b'hi')
。