python将十六进制字符串转换为格式化二进制字符串

时间:2016-08-24 21:08:31

标签: python binary hex

来自输入0x1234 我需要输出:0b0001_0010_0011_0100

我可以想到做到这一点的所有不好的方法,但是实现这一目标的最蟒蛇方法是什么。

我可以轻松转换为bin字符串(bin(int('0x1234', 16)),但这只会给我0001001000110100。我需要一个_之间的半字节。

谢谢。

3 个答案:

答案 0 :(得分:4)

hex将一个数字映射到一个半字节...所以你可以用查找表轻松地完成它

hex2bin_map = {
   "0":"0000",
   "1":"0001",
   "2":"0010",
   "3":"0011",
   "4":"0100",
   "5":"0101",
   "6":"0110",    
   "7":"0111",
   "8":"1000",
   "9":"1001",
   "A":"1010",
   "B":"1011",
   "C":"1100",
   "D":"1101",
   "E":"1110",
   "F":"1111",
}
hex_num="1234"
print "_".join(hex2bin_map[i] for i in hex_num)
# 0001_0010_0011_0100

这不像其他答案一样简洁......但它可能是最高效的...而且它的相当容易阅读(即你不需要担心拉链的石斑图案,也不需要担心正则表达式,这必然会混淆新的程序员)

答案 1 :(得分:2)

作为generic sequence chunking的替代方案,对于字符串,您可以使用正则表达式进行分组和替换:

>>> '0b' + re.sub(r'(\d{4})(?!$)', r'\1_', format(int('0x1234', 16), '016b'))
'0b0001_0010_0011_0100'

在Python 3.6中,您可以使用格式说明符执行此操作(请参阅PEP 515

'0b' + format(int('0x1234', 16), '016_b')

或者,如果您愿意:

'0b{:016_b}'.format(int('0x1234', 16))

答案 2 :(得分:1)

不确定是否有更好的方法,但这有效(假设数字总是16位):

# Takes a hex-encoded 16-bit number and returns a binary representation with
# leading zeros and underscores as a nibble separator.
def binary_representation(string):
    return '0b' + '_'.join(
        ''.join(nibble) for nibble in zip(*([iter('{:>016b}'.format(int(string, 16)))]*4)))

assert binary_representation('0x1234') == '0b0001_0010_0011_0100'

来自grouper example in the Python docszip技巧很好。该调用基本上会发出[('0', '0', '0', '1'), ('0', '0', '1', '0'), ...]。从那里,你只需要将每个半字节变成一个字符串然后用下划线将它们全部连接起来。

这里另一个有趣的位是{:>016b}格式,它为您提供了数字的右对齐,零填充二进制表示。如果您需要支持不同大小的数字,这是您需要更改的部分。

<强>更新

鉴于您的号码以字符串开头,这种方法更简单,受到@ Joran答案的启发,但没有查找表。

def binary_representation(string):
    return '0b' + '_'.join(['{:>04b}'.format(int(d, 16)) for d in string[2:]])