Python以大十六进制数获取特定字节

Python以大十六进制数获取特定字节,python,bit-manipulation,byte,Python,Bit Manipulation,Byte,假设我有一个大十六进制数0x1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF 我想从这个十六进制数中轻松地得到10-20字节,我该如何实现呢?我知道我可以将数据从位右移中剪切10*8次,但我的左上角十六进制数中仍然有有效字节。最简单的方法是使用字符串切片。由于

假设我有一个大十六进制数0x1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF


我想从这个十六进制数中轻松地得到10-20字节,我该如何实现呢?我知道我可以将数据从位右移中剪切10*8次,但我的左上角十六进制数中仍然有有效字节。

最简单的方法是使用字符串切片。由于最低字节在最右边,最高字节在左边,我们可以使用负索引

def sub_bytes(i, start=0, end=0):
    i_str = hex(i)[2:]  # skip 0x part
    i_sub = i_str[-end * 2: len(i_str) - start * 2]  # get the bytes we need
    return int(i_sub or '0', 16)  # convert to back int
len(i_str)
用于更好的start=0处理

让我们试试你的价值观

In [2]: value = 0x1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF

In [3]: sub_bytes(value, 0, 3)
Out[3]: 11259375

In [4]: hex(sub_bytes(value, 0, 3))
Out[4]: '0xabcdef'

In [6]: hex(sub_bytes(value, 10, 20))
Out[6]: '0x90abcdef1234567890ab'

In [7]: hex(sub_bytes(value, 45))
Out[7]: '0x123456'
如果请求的片为空或超出范围,我在这里返回0x0,但如果愿意,您可以提高
索引器

更新

在Python3.2+中,在
int
上定义了更高效、更方便的

import math

def slice_bytes(value, a=None, b=None, byteorder='little'):
    size = math.ceil(value.bit_length() / 8)
    value_bytes = value.to_bytes(size, byteorder)
    return int.from_bytes(value_bytes[a: b], byteorder)

在对一个包含288998字节的数字
7**7**7
进行性能测试后,我发现
slice_bytes
比Karl的直接方法更快<代码>子字节显然较慢。

与字符串和子字符串相比,我觉得位掩码方法是获取所需位的更直接的方法。在您的评论中,您提到位掩码将非常大,这是事实,但这不是程序的问题

我有一个示例函数,它可以根据您希望从数据中获取的字节数为您制作一个掩码。然后您只需使用右移值
遮罩即可获得所需的值

假设您希望从字节索引2开始获取4个字节的数据:

def get_bytes(value, start, amount):  
    shifted_value = value >> (start * 8) # Multiply by 8 for how much to right shift
    mask = make_mask(amount) 
    return shifted_value & mask

def make_mask(byte_amount):
    if byte_amount > 0:
        bin_string = '1' * (byte_amount * 8)  # Create binary string mask
    else:
        bin_string = '0'  # Make result 0
    return int(bin_string, 2)  # Return integer representation

value = 0x1234567890ABCDEF1234567890ABCDEF
result = get_bytes(value, 2, 4)

结果是结果十进制整数中的
1450741931
,该整数转换为十六进制的
0x567890ab

它只是一个十六进制数字串?这是一个简单的数学:
index=(pos*2)
,基本pos=1。所以第一个字节是
pos=1
,因此
index=2
在一个基于零的数组中。。。。然后取10*2个数字得到10个字节。你可以使用位掩码和位移位值来只得到你需要的位。但是我的位掩码将是巨大的@Karl,它类似于0xFFFFFFFFFFFFFF。字节10-20只是一个例子,我想用大约40字节的字节数来描述它!目前这是可行的,我想看看是否有更有效的方法来使用位操作,但我想没有:)你会如何提高索引器?现在,您在return语句中默认返回0。如果不是,我会在return语句之前写
:raise indexer(“片中没有字节”)
或类似的内容