Python 将位写入二进制文件
我有23位表示为一个字符串,我需要将这个字符串作为4个字节写入一个二进制文件。最后一个字节总是0。下面的代码可以工作(Python3.3),但感觉不是很优雅(我对Python和编程相当陌生)。你有什么办法让它变得更好吗?for循环似乎很有用,但是如何在循环中进行切片而不使用索引器呢?请注意,当我将位提取到一个字节中时,我会反转位顺序Python 将位写入二进制文件,python,python-3.x,Python,Python 3.x,我有23位表示为一个字符串,我需要将这个字符串作为4个字节写入一个二进制文件。最后一个字节总是0。下面的代码可以工作(Python3.3),但感觉不是很优雅(我对Python和编程相当陌生)。你有什么办法让它变得更好吗?for循环似乎很有用,但是如何在循环中进行切片而不使用索引器呢?请注意,当我将位提取到一个字节中时,我会反转位顺序 from array import array bin_array = array("B") bits = "10111111111111111011110"
from array import array
bin_array = array("B")
bits = "10111111111111111011110" #Example string. It's always 23 bits
byte1 = bits[:8][::-1]
byte2 = bits[8:16][::-1]
byte3 = bits[16:][::-1]
bin_array.append(int(byte1, 2))
bin_array.append(int(byte2, 2))
bin_array.append(int(byte3, 2))
bin_array.append(0)
with open("test.bnr", "wb") as f:
f.write(bytes(bin_array))
# Writes [253, 255, 61, 0] to the file
您可以将其视为int,然后按如下方式创建4个字节:
>>> bits = "10111111111111111011110"
>>> int(bits[::-1], 2).to_bytes(4, 'little')
b'\xfd\xff=\x00'
模块是为这样的事情而设计的——考虑下面的内容,其中转换为字节已经被分解成一些不必要的中间步骤以使其更清楚:
import struct
bits = "10111111111111111011110" # example string. It's always 23 bits
int_value = int(bits[::-1], base=2)
bin_array = struct.pack('i', int_value)
with open("test.bnr", "wb") as f:
f.write(bin_array)
一种较难阅读但较短的方法是:
bits = "10111111111111111011110" # example string. It's always 23 bits
with open("test.bnr", "wb") as f:
f.write(struct.pack('i', int(bits[::-1], 2)))
可以使用以下方法在一行中执行拆分: 作为一种算法,您可以将
位填充到长度32,然后使用re.findall
方法将其分组为八位:
>>> bits
'10111111111111111011110000000000'
>>> re.findall(r'\d{8}', bits)
['10111111', '11111111', '10111100', '00000000']
您的代码如下所示:
import re
from array import array
bin_array = array("B")
bits = "10111111111111111011110".ljust(32, '0') # pad it to length 32
for octect in re.findall(r'\d{8}', bits): # split it in 4 octects
bin_array.append(int(octect[::-1], 2)) # reverse them and append it
with open("test.bnr", "wb") as f:
f.write(bytes(bin_array))
填充将更加明确,如bits=“10111111111011110”.ljust(32,'0')
@Jon,即。。。太神了有可能走另一条路吗?类似于:int.from_bytes(b'\xfd\xff=\x00','little')
和get“10111111111011110”
@Olav,是的-适当地格式化:格式(int.from_bytes(b'\xfd\xff=\x00','little'),'023b')[::-1]
这个问题在这个网站上被问了很多次,但这是所有答案中唯一合理的解决方案you@YungGun:直到版本3.2才添加到Python中,因此为了与当前和旧版本的语言兼容,使用struct
模块(如中所示)可能更可取,因为它将同时在Python 2.x和3.x中工作。@Kebman实际上不是。。。看见
>>> bits
'10111111111111111011110000000000'
>>> re.findall(r'\d{8}', bits)
['10111111', '11111111', '10111100', '00000000']
import re
from array import array
bin_array = array("B")
bits = "10111111111111111011110".ljust(32, '0') # pad it to length 32
for octect in re.findall(r'\d{8}', bits): # split it in 4 octects
bin_array.append(int(octect[::-1], 2)) # reverse them and append it
with open("test.bnr", "wb") as f:
f.write(bytes(bin_array))