在 Python 3 中将二进制字符串转换为 bytearray [英] Convert binary string to bytearray in Python 3

查看:51
本文介绍了在 Python 3 中将二进制字符串转换为 bytearray的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管有很多相关问题,但我找不到与我的问题相符的问题.我想将二进制字符串(例如,"0110100001101001")更改为字节数组(相同的示例,b"hi").

我试过这个:

bytes([int(i) for i in "0110100001101001"])

但我得到了:

b'\x00\x01\x01\x00\x01' #...等等

在 Python 3 中执行此操作的正确方法是什么?

解决方案

以下是 Patrick 提到的第一种方法的示例:将位串转换为 int 并一次取 8 位.这样做的自然方法是以相反的顺序生成字节.为了将字节恢复到正确的顺序,我在字节数组上使用扩展切片符号,步长为 -1:b[::-1].

def bitstring_to_bytes(s):v = int(s, 2)b = 字节数组()而 v:b.append(v & 0xff)v >>= 8返回字节(b[::-1])s = 0110100001101001"打印(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 例如,
47//10 给出 4,并且

-47//10 给出 -5.所以

-(-47//10) 给出 5,有效地执行天花板分割.

因此在 bitstring_to_bytes 中我们可以做到:

return int(s, 2).to_bytes(-(-len(s)//8), byteorder='big')

然而,并没有多少人熟悉这种高效&紧凑的习语,所以通常认为它的可读性不如

return (s, 2).to_bytes((len(s) + 7)//8, byteorder='big')

Despite the many related questions, I can't find any that match my problem. I'd like to change a binary string (for example, "0110100001101001") into a byte array (same example, b"hi").

I tried this:

bytes([int(i) for i in "0110100001101001"])

but I got:

b'\x00\x01\x01\x00\x01' #... and so on

What's the correct way to do this in Python 3?

解决方案

Here's an example of doing it the first way that Patrick mentioned: convert the bitstring to an int and take 8 bits at a time. The natural way to do that generates the bytes in reverse order. To get the bytes back into the proper order I use extended slice notation on the bytearray with a step of -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))

Clearly, Patrick's second way is more compact. :)

However, there's a better way to do this in Python 3: use the int.to_bytes method:

def bitstring_to_bytes(s):
    return int(s, 2).to_bytes((len(s) + 7) // 8, byteorder='big')


If len(s) is guaranteed to be a multiple of 8, then the first arg of .to_bytes can be simplified:

return int(s, 2).to_bytes(len(s) // 8, byteorder='big')

This will raise OverflowError if len(s) is not a multiple of 8, which may be desirable in some circumstances.


Another option is to use double negation to perform ceiling division. For integers a & b, floor division using //

n = a // b

gives the integer n such that
n <= a/b < n + 1
Eg,
47 // 10 gives 4, and

-47 // 10 gives -5. So

-(-47 // 10) gives 5, effectively performing ceiling division.

Thus in bitstring_to_bytes we could do:

return int(s, 2).to_bytes(-(-len(s) // 8), byteorder='big')

However, not many people are familiar with this efficient & compact idiom, so it's generally considered to be less readable than

return (s, 2).to_bytes((len(s) + 7) // 8, byteorder='big')

这篇关于在 Python 3 中将二进制字符串转换为 bytearray的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆