Python 保留前导零的二进制到十六进制转换

Python Binary to hex conversion preserving leading zeroes

我想将 576 位二进制数转换为十六进制,所以我编写了以下 python 脚本。虽然写它很有趣,但我认为它庞大、丑陋,而且很可能不必要地复杂。我想知道是否有人使用一些内置的 python 来使用更有效的方法来做到这一点。我使用我能找到的任何东西的问题是保留前导零,因为它绝对是关键的。以下是我用来测试的输入和输出以及我编写的代码。

输入:

000011110111101011000101

输出:

0f7ac5

代码

file = open("binforhex.txt",'r')
stream = file.read()

num = []
byte = []
hexOut = []
n = 0

print stream

for x in stream:
    num.append(x)


while n < len(num):
    byte.append(int(num[n]))
    if n > 1:
        if (n + 1) % 4  == 0:
            if cmp([0, 0, 0, 0],byte) == 0 :
                hexOut.append('0')
            elif cmp([0, 0, 0, 1],byte) == 0 :
                hexOut.append('1')
            elif cmp([0, 0, 1, 0],byte) == 0 :
                hexOut.append('2')
            elif cmp([0, 0, 1, 1],byte) == 0 :
               hexOut.append('3')
            elif cmp([0, 1, 0, 0],byte) == 0:
                hexOut.append('4')
            elif cmp([0, 1, 0, 1],byte) == 0:
                hexOut.append('5')
            elif cmp([0, 1, 1, 0],byte) == 0:
                hexOut.append('6')
            elif cmp([0, 1, 1, 1],byte) == 0:
                hexOut.append('7')
            elif cmp([1, 0, 0, 0],byte) == 0:
                hexOut.append('8')
            elif cmp([1, 0, 0, 1],byte) == 0:
                hexOut.append('9')
            elif cmp([1, 0, 1, 0],byte) == 0:
                hexOut.append('a')
            elif cmp([1, 0, 1, 1],byte) == 0:
                hexOut.append('b')
            elif cmp([1, 1, 0, 0],byte) == 0:
                hexOut.append('c')
            elif cmp([1, 1, 0, 1],byte) == 0:
                hexOut.append('d')
            elif cmp([1, 1, 1, 0],byte) == 0:
                hexOut.append('e')
            elif cmp([1, 1, 1, 1],byte) == 0 :
                hexOut.append('f')
            byte.pop()
            byte.pop()
            byte.pop()
            byte.pop()
    n += 1
print ''.join(hexOut)

您知道有一个 hex() 内置功能吗?它将任何数字(包括二进制数,以0b开头)转换为十六进制字符串:

>>> hex(0b000011110111101011000101)
'0xf7ac5'

你想要的十六进制数字总数,从二进制字符串b开始,是

hd = (len(b) + 3) // 4

所以...:[=​​18=]

x = '%.*x' % (hd, int('0b'+b, 0))

应该给你你想要的(当然,你可以很容易地切掉一个'0x'前缀,只需使用x[2:])。

补充:格式字符串'%.*x'表示"format as hexadecimal to a length as per supplied parameter, with leading zeros"。这里的"supplied parameter"就是hd,我们需要的十六进制数字的总数。

简单、关键的概念是根据总位数(输入为二进制,输出为十六进制)而不是每种情况下的 "number of leading zeros" 来考虑——后者将恰到好处。例如,如果输入的二进制字符串有 576 位,无论其中有多少 "leading zeros",您希望输出的十六进制字符串具有 576 // 4,即 144 个十六进制数字,所以这就是 hd 将被设置为 -- 这就是您将通过这种格式获得的位数(其中许多将根据需要 "leading zeros" -- 不多也不少)。