【问题标题】:python convert hex string to formated binary string [closed]python将十六进制字符串转换为格式化的二进制字符串[关闭]
【发布时间】:2016-08-24 21:08:30
【问题描述】:

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

我能想到所有不好的方法来做到这一点,但实现这一点的最 Pythonic 的方法是什么。

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

谢谢。

【问题讨论】:

  • 到目前为止你尝试了哪些方法?
  • 你知道 for 循环、切片和列表推导吗?如果你这样做,我认为你可以在一两行中做到这一点
  • 我将字符串转换为位数组,然后循环位数组并在每个第 4 个元素上添加“_”,然后将其打印出来。很像一个 c 函数。
  • 显示你的代码

标签: python binary hex


【解决方案1】:

十六进制将一个数字映射到一个半字节...因此您可以使用查找表轻松完成此操作

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

我确定这不像其他答案那样简洁......但它可能是性能最高的......而且它非常易于阅读(即你不需要担心 zip 的石斑鱼模式,也不需要担心正则表达式,这势必会让新手程序员感到困惑)

【讨论】:

  • 我喜欢这样可以避免从字符串 -> 数字 -> 回字符串的迂回转换。
  • 加上 dict 查找是 O(1) ......这真的是好处...... str->num->str 真的是一个非常快速的操作
  • 谢谢!。这是有道理的。
  • 不错的方法!受此启发,我在我的答案中添加了第二种方法,它与此非常相似,但避免了查找表。 (此外,您缺少对输入开头的“0x”和输出开头预期的“0b”的处理。)
【解决方案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))

【讨论】:

    【解决方案3】:

    不确定是否有更好的方法,但这可行(假设数字始终为 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'
    

    zip 技巧是来自grouper example in the Python docs 的一个很好的技巧。该调用实质上发出[('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:]])
    

    【讨论】:

    • 谢谢。看起来行得通。
    猜你喜欢
    • 2019-08-23
    • 1970-01-01
    • 2017-05-26
    • 2017-02-23
    • 2014-08-03
    • 2015-06-21
    • 2014-10-24
    • 2012-03-04
    相关资源
    最近更新 更多