我想替换表示十六进制符号的字节类型对象中的单个符号。
print(type(a)) # --> <class 'bytes'>
从a = b'2900BC'
开始,我想通过调用一些类似于
a = b'29F0BC'
的形式结束
replace_hex_symbol(input, index, value)
就我而言
replace_hex_symbol(a,2,F)
意味着将对象a中的符号编号2设置为F的值(因为f_hex = 1111_bin)
据我了解,一个问题是字节类型的对象是不可变的。即使将其转换为字节数组,我似乎也无法完成。 python中是否已经有一种好的方法来实现这种操作,或者有人巧妙地技巧了如何替换该对象中充满十六进制符号的部分?
答案 0 :(得分:0)
bytes
对象通常具有与字符串相同的方法。两者都是不可变的,但这不会阻止您根据旧值创建新对象。
例如,您可以创建一个新的bytes
值,将所有2
个ASCII字符替换为F
的ASCII字符并替换为bytes.replace()
method:
>>> b'2900BC'.replace(b'2', b'F')
b'F900BC'
有关受支持的方法列表,请参见Python标准类型文档的Bytes and Bytearray Operations section。请注意,bytes.replace()
的参数本身必须带有bytes
值!
根据您的replace_hex_symbol()
函数:
def replace_hex_symbol(a, old, new):
# ensure that both old and new are actually bytes
if not isinstance(old, bytes):
old = old.encode('ascii')
if not isinstance(new, bytes):
new = new.encode('ascii')
return a.replace(old, new)
接下来,bytearray
对象基本上是bytes
的可变子类;它们具有相同的方法,但是您也可以直接处理索引并进行更新。参见Mutable Sequence Types documentation。
bytes
和bytearray
对象都是0-255范围内的整数的序列,索引可以反映这一点。分配给bytearray
的单个索引时,必须使用整数:
>>> b = bytearray(b'2900BC')
>>> b
bytearray(b'2900BC')
>>> b[0]
50
>>> b[0] = ord('F') # ascii codepoint for F
>>> b
bytearray(b'F900BC')
,但是您也可以使用切片(包括分配)进行索引,这时您在获取时会再次获得相同的序列对象,并且可以接受任何字节序列(包括bytes
对象或整数列表)
但是,当您要替换十六进制字符时,索引更新就地访问bytesarray
会变得更加麻烦。
实际上,关于十六进制字符序列,没有任何内容声明它们必须为bytes
值!如果必须具有可变类型,则也可以使用str
对象或单个十六进制数字列表:
>>> '2900BC' # string
'2900BC'
>>> list('2900BC') # list of characters
['2', '9', '0', '0', 'B', 'C']
如果您要以十六进制数字处理已被编码的二进制数据,请使用bytes.fromhex()
factory method将该编码数据转换为bytes
值,然后返回{{ 3}}; bytearray
个对象支持相同的转换。
此时,十六进制数字将分别转换为4位半字节,并且您需要均匀的十六进制数字长度:
>>> bytes.fromhex('2900BC')
b')\x00\xbc'
>>> list(bytes.fromhex('2900BC')) # show individual byte integer values
[41, 0, 188]
,您必须使用位移和掩码来设置单个半字节。例如,输入十六进制中的2
是第一个字节中最重要的半字节,因此F
十六进制或15
十进制将需要移位4位,并且然后与第一个字节的低4位组合:
>>> a = bytearray.fromhex('2900BC') # mutable sequence of 3 bytes
>>> a[0] = (0xF << 4) | (a[0] & 0xF) # set upper nibble, preserve lower
>>> a
bytearray(b'\xf9\x00\xbc')
>>> a.hex()
'f900bc'
请参阅Python Wiki上的bytes.hex()
。但是,如果您需要更大规模的操作,请考虑使用bit manipulation page之类的第三方库来简化操作。