在python中将字节转换为位

时间:2012-01-11 07:23:19

标签: python hex byte bits

我正在使用Python3.2。我需要将十六进制流作为输入并在位级解析它。所以我用了

bytes.fromhex(input_str)

将字符串转换为实际字节。现在我如何将这些字节转换为位?

10 个答案:

答案 0 :(得分:31)

另一种方法是使用bitstring模块:

>>> from bitstring import BitArray
>>> input_str = '0xff'
>>> c = BitArray(hex=input_str)
>>> c.bin
'0b11111111'

如果您需要删除前导0b

>>> c.bin[2:]
'11111111'

bitstring模块不是必需的,正如 jcollado 的回答所示,但它有很多高性能的方法可以将输入转换为位并对其进行操作。您可能会发现这个方便(或不),例如:

>>> c.uint
255
>>> c.invert()
>>> c.bin[2:]
'00000000'

答案 1 :(得分:19)

当您在整数级别工作时,操作会快得多。特别是,转换为此处建议的字符串非常慢。

如果只需要第7位和第8位,请使用例如

val = (byte >> 6) & 3

(这是:将字节6位向右移位 - 丢弃它们。然后只保留最后两位3是设置前两位的数字...)

这些可以很容易地转换为超快的简单CPU操作。

答案 2 :(得分:17)

这样的事情怎么样?

>>> bin(int('ff', base=16))
'0b11111111'

这会将您拥有的十六进制字符串转换为整数,并将该整数转换为每个字节设置为0/1的字符串,具体取决于整数的位值。

正如评论所指出的,如果你需要摆脱0b前缀,你可以这样做:

>>> bin(int('ff', base=16)).lstrip('0b')
11111111

或者这样:

>>> bin(int('ff', base=16))[2:]
11111111

答案 3 :(得分:7)

二进制:

bin(byte)[2:].zfill(8)

答案 4 :(得分:4)

我认为最简单的就是在这里使用numpy。例如,您可以将文件作为字节读取,然后将其轻松扩展为位:

Bytes = numpy.fromfile(filename, dtype = "uint8")
Bits = numpy.unpackbits(Bytes)

答案 5 :(得分:2)

读取读取字节时使用ord

byte_binary = bin(ord(f.read(1))) # Add [2:] to remove the "0b" prefix

使用str.format()

'{:08b}'.format(ord(f.read(1)))

答案 6 :(得分:1)

使用python format string syntax

>>> mybyte = bytes.fromhex("0F") # create my byte using a hex string
>>> binary_string = "{:08b}".format(int(mybyte.hex(),16))
>>> print(binary_string)
00001111

第二行是魔术发生的地方。所有字节对象都有一个.hex()函数,该函数返回一个十六进制字符串。使用此十六进制字符串,我们将其转换为整数,告诉int()函数它是基数为16的字符串(因为十六进制是基数为16)。然后,我们将格式化应用于该整数,以使其显示为二进制字符串。 {:08b}是真正的魔术发生的地方。它正在使用Format Specification Mini-Language format_spec。具体来说,它使用format_spec语法的widthtype部分。 8width设置为8,这就是我们获得漂亮的0000填充的方式,而b将类型设置为二进制。

bin()方法相比,我更喜欢这种方法,因为使用格式字符串可以提供更大的灵活性。

答案 7 :(得分:0)

以下是如何使用format()

执行此操作
print "bin_signedDate : ", ''.join(format(x, '08b') for x in bytevector)
  

重要的是 08b 。这意味着它将最多附加8个前导零以完成一个字节。如果不指定此格式,则每个转换后的字节格式只有一个可变位长度。

答案 8 :(得分:0)

此处的其他答案以big-endian顺序提供位('\x01'变为'00000001'

如果您对小端的位顺序感兴趣,这在许多情况下很有用,比如bignums的常见表示等 - 这是一个片段:

def bits_little_endian_from_bytes(s):
    return ''.join(bin(ord(x))[2:].rjust(8,'0')[::-1] for x in s)

另一方面:

def bytes_from_bits_little_endian(s):
    return ''.join(chr(int(s[i:i+8][::-1], 2)) for i in range(0, len(s), 8))

答案 9 :(得分:0)

input_str = "ABC"
[bin(byte) for byte in bytes(input_str, "utf-8")]

会给:

['0b1000001', '0b1000010', '0b1000011']