python字节到位字符串

用户名

我有bytes需要转换为的类型的值BIT STRING

bytes_val = (b'\x80\x00', 14)

索引0中的字节需要转换为长度的位串,如第二个元素所示(本例中为14),并格式化为8位组,如下所示。

预期输出=> '10000000 000000'B

另一个例子

bytes_val2 = (b'\xff\xff\xff\xff\xf0\x00', 45) #=> '11111111 11111111 11111111 11111111 11110000 00000'B
norok2

格式化(在f字符串下方,但可以通过其他方式完成)和切片的某种组合呢?

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章