按地址范围切片十六进制字符串

时间:2017-02-09 03:21:15

标签: python python-2.7 hex bit-manipulation

假设我有一个十六进制字符串:

EPC = '00000800031C1060EC9FBD3C00000000'

规范文档指定字符串表示的不同字段的地址范围。对于例如地址范围48h-53h(12位),代表'代理'字段。我知道(根据经验)这在六角形EPC中代表3个半字节“1C1”。

同样,我希望能够解码具有指定地址范围的其他字段,所以我的问题是:

如何使用规范中的地址范围信息从十六进制字符串EPC中提取它所代表的半字节?更具体地说,我正在寻找以下类型的功能:

def fun(addressrangeinhex,bits, hexstring):
    # addressrangeinhex is 48h-53h in my example above
    # hexstring is EPC string in my example above
    # bits is 12 bits in my example above
    return rangeofindexinhexstring

所以使用我的例子中的函数我应该得到(index = 10,index = 12)。

2 个答案:

答案 0 :(得分:2)

在比特字符串和索引中有它:

bits = '{0:0128b}'.format(int(EPC,16))
agency = int(bits[40:52],2)

print(hex(agency))  # 1C1

答案 1 :(得分:1)

此解决方案采用指定要使用规范中的字符串提取的位的方法。即:'48h-53h'。从中提取那些寄存器位的十六进制值也应该是一个字符串。此外,此函数可以获取不在半字节边界上的值。

<强>代码:

def get_sub_register_value(sub_reg_bits_addr, bit_string):
    """
    Given a register address description string, and a register value
    string, return the bits from the value described by the address

    :param sub_reg_bits_addr: string of the form '48h-53h'
    :param bit_string: register value string of the form,
        '00000800031C1060EC9FBD3C00000000'
    :return: returns string of sub register: eg
    """
    start, end = (int(x[:-1], 16) for x in sub_reg_bits_addr.split('-'))
    value = int(bit_string, 16)
    mask = (1 << (end - start + 1)) - 1
    return ("%x" % ((value >> start) & mask)).upper()

测试数据:

EPC = '00000800031C1060EC9FBD3C0000000'
agency = '48h-53h'
pattern = 'FEDCBA98765432109876543210'

assert get_sub_register_value(agency, EPC) == '1C1'
assert get_sub_register_value('0h-3h', pattern) == '0'
assert get_sub_register_value('1h-4h', pattern) == '8'
assert get_sub_register_value('5h-8h', pattern) == '0'
assert get_sub_register_value('5h-9h', pattern) == '10'
assert get_sub_register_value('4h-9h', pattern) == '21'
assert get_sub_register_value('3h-9h', pattern) == '42'