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



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

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

因此,在我的示例中使用该函数,我应该得到(索引=10,索引=12(。

把它放在位字符串中并在那里索引:

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

此解决方案采用使用规范中的字符串指定要提取的位的方法。 即:'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'

最新更新