2024-04-24 22:18:21 发布
网友
尽管有很多相关的问题,我还是找不到与我的问题相符的。我想将二进制字符串(例如,"0110100001101001")更改为字节数组(同样的示例,b"hi")。
"0110100001101001"
b"hi"
我试过这个:
bytes([int(i) for i in "0110100001101001"])
但我得到了:
b'\x00\x01\x01\x00\x01' #... and so on
在Python 3中,正确的方法是什么?
下面是一个例子,按照Patrick提到的第一种方法:将位字符串转换为int,一次取8位。按相反顺序生成字节的自然方法。为了使字节回到正确的顺序,我在bytearray上使用扩展切片表示法,步骤是-1:b[::-1]。
b[::-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))
很明显,帕特里克的第二条路更紧凑。:)
但是,在Python 3中有一个更好的方法:使用int.to_bytes方法:
def bitstring_to_bytes(s): return int(s, 2).to_bytes(len(s) // 8, byteorder='big')
你要么把它转换成一个int,一次取8位,要么把它切碎成8字节长的字符串,然后把每个字符串转换成int。在Python 3中,正如PM 2Ring和J.F Sebastian的答案所示,int的to_bytes()方法允许您非常高效地执行第一个方法。这在Python2中是不可用的,所以对于坚持使用这种方法的人来说,第二种方法可能更有效。下面是一个例子:
int
to_bytes()
>>> s = "0110100001101001" >>> bytes(int(s[i : i + 8], 2) for i in range(0, len(s), 8)) b'hi'
为了分解这一点,range语句从索引0开始,将索引放入源字符串中,但一次前进8个索引。由于s有16个字符长,它将为我们提供两个索引:
s
>>> list(range(0, 50, 8)) [0, 8, 16, 24, 32, 40, 48] >>> list(range(0, len(s), 8)) [0, 8]
(我们在这里使用list()来显示将从Python 3中的范围迭代器检索的值。)
list()
然后,我们可以在此基础上将字符串分成8个字符:
>>> [s[i : i + 8] for i in range(0, len(s), 8)] ['01101000', '01101001']
然后我们可以把它们转换成整数,基2:
>>> list(int(s[i : i + 8], 2) for i in range(0, len(s), 8)) [104, 105]
最后,我们用bytes()把整个过程包装起来,得到答案:
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')。
bytes
bytearray
bytearray(b'hi')
下面是一个例子,按照Patrick提到的第一种方法:将位字符串转换为int,一次取8位。按相反顺序生成字节的自然方法。为了使字节回到正确的顺序,我在bytearray上使用扩展切片表示法,步骤是-1:
b[::-1]
。很明显,帕特里克的第二条路更紧凑。:)
但是,在Python 3中有一个更好的方法:使用int.to_bytes方法:
你要么把它转换成一个int,一次取8位,要么把它切碎成8字节长的字符串,然后把每个字符串转换成int。在Python 3中,正如PM 2Ring和J.F Sebastian的答案所示,
int
的to_bytes()
方法允许您非常高效地执行第一个方法。这在Python2中是不可用的,所以对于坚持使用这种方法的人来说,第二种方法可能更有效。下面是一个例子:为了分解这一点,range语句从索引0开始,将索引放入源字符串中,但一次前进8个索引。由于
s
有16个字符长,它将为我们提供两个索引:(我们在这里使用
list()
来显示将从Python 3中的范围迭代器检索的值。)然后,我们可以在此基础上将字符串分成8个字符:
然后我们可以把它们转换成整数,基2:
最后,我们用
bytes()
把整个过程包装起来,得到答案:它返回一个不可变字节序列的
bytes
对象。如果你想得到一个bytearray
——一个可变字节序列——那么只要调用bytearray(b'hi')
。相关问题 更多 >
编程相关推荐