python - python字节到位字符串
问题描述
我有bytes
需要转换为的类型的值BIT STRING
bytes_val = (b'\x80\x00', 14)
索引零中的字节需要转换为长度由第二个元素(在本例中为 14)指示的位串,并格式化为 8 位组,如下所示。
预期输出 =>'10000000 000000'B
另一个例子
bytes_val2 = (b'\xff\xff\xff\xff\xf0\x00', 45) #=> '11111111 11111111 11111111 11111111 11110000 00000'B
解决方案
一些格式的组合(下面是 f-string,但可以用其他方式)和切片:
def bytes2binstr(b, n=None):
s = ' '.join(f'{x:08b}' for x in b)
return s if n is None else s[:n + n // 8 + (0 if n % 8 else -1)]
如果我理解正确(我不确定B
最后应该是什么意思),它会通过您的测试和更多测试:
func = bytes2binstr
args = (
(b'\x80\x00', None),
(b'\x80\x00', 14),
(b'\x0f\x00', 14),
(b'\xff\xff\xff\xff\xf0\x00', 16),
(b'\xff\xff\xff\xff\xf0\x00', 22),
(b'\x0f\xff\xff\xff\xf0\x00', 45),
(b'\xff\xff\xff\xff\xf0\x00', 45),
)
for arg in args:
print(arg)
print(repr(func(*arg)))
# (b'\x80\x00', None)
# '10000000 00000000'
# (b'\x80\x00', 14)
# '10000000 000000'
# (b'\x0f\x00', 14)
# '00001111 000000'
# (b'\xff\xff\xff\xff\xf0\x00', 16)
# '11111111 11111111'
# (b'\xff\xff\xff\xff\xf0\x00', 22)
# '11111111 11111111 111111'
# (b'\x0f\xff\xff\xff\xf0\x00', 45)
# '00001111 11111111 11111111 11111111 11110000 00000'
# (b'\xff\xff\xff\xff\xf0\x00', 45)
# '11111111 11111111 11111111 11111111 11110000 00000'
解释
- 我们从一个
bytes
对象开始 - 遍历它会给我们一个字节作为数字
- 每个字节是 8 位,所以解码已经给了我们正确的分离
- 每个字节都使用
b
二进制说明符进行格式化,并带有一些额外的格式:0
零填充,8
最小长度 ' '
我们使用“分隔符”连接(连接)格式化的结果n
最后,如果未指定最大位数(设置为None
),则按原样返回结果,否则将结果裁剪为n
+ 在 8 个字符组之间添加的空格数。
在上面的解决方案8
中有些硬编码。如果您希望它成为一个参数,您可能需要查看(可能是)@kederrac 的第一个答案使用int.from_bytes()
. 这可能看起来像:
def bytes2binstr_frombytes(b, n=None, k=8):
s = '{x:0{m}b}'.format(m=len(b) * 8, x=int.from_bytes(b, byteorder='big'))[:n]
return ' '.join([s[i:i + k] for i in range(0, len(s), k)])
这给出了与上面相同的输出。
Speedwise,int.from_bytes()
基于 - 的解决方案也更快:
for i in range(2, 7):
n = 10 ** i
print(n)
b = b''.join([random.randint(0, 2 ** 8 - 1).to_bytes(1, 'big') for _ in range(n)])
for func in funcs:
print(func.__name__, funcs[0](b, n * 7) == func(b, n * 7))
%timeit func(b, n * 7)
print()
# 100
# bytes2binstr True
# 10000 loops, best of 3: 33.9 µs per loop
# bytes2binstr_frombytes True
# 100000 loops, best of 3: 15.1 µs per loop
# 1000
# bytes2binstr True
# 1000 loops, best of 3: 332 µs per loop
# bytes2binstr_frombytes True
# 10000 loops, best of 3: 134 µs per loop
# 10000
# bytes2binstr True
# 100 loops, best of 3: 3.29 ms per loop
# bytes2binstr_frombytes True
# 1000 loops, best of 3: 1.33 ms per loop
# 100000
# bytes2binstr True
# 10 loops, best of 3: 37.7 ms per loop
# bytes2binstr_frombytes True
# 100 loops, best of 3: 16.7 ms per loop
# 1000000
# bytes2binstr True
# 1 loop, best of 3: 400 ms per loop
# bytes2binstr_frombytes True
# 10 loops, best of 3: 190 ms per loop
推荐阅读
- mysql - Mysql序列列生成
- c# - Azure 文件共享属性 LastModified 的空值
- access-token - AcquireTokenSilentAsync 不起作用
- php - PHP在字符限制上剪切字符串
- c# - MongoDB C# 驱动程序和过滤位置运算符 $[
] 使用类型化 API - python - 根据特定列中的不同范围值对多个数据帧进行切片,并将它们分类到新列中
- swift - locationManager.startMonitoring(for: region) 错误?
- sql - SQL - 为所有符合条件的 id 查找 id
- javascript - 使用 react/redux 搜索/过滤列表
- excel-formula - 多张纸的计数