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