我正在使用Python3.2。我需要将十六进制流作为输入并在位级解析它。所以我用了
bytes.fromhex(input_str)
将字符串转换为实际字节。现在我如何将这些字节转换为位?
答案 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语法的width
和type
部分。 8
将width
设置为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']