【问题标题】:Bitwise operations on strings Python3.7字符串的按位运算 Python3.7
【发布时间】:2019-04-21 16:37:58
【问题描述】:

我有一大串十六进制数字,我想对其执行一些按位运算。我试图从中提取不同的字节,然后应用按位 OR、AND、XOR 操作。不幸的是,我不知道一个简单的方法来做到这一点,所以每次我想执行按位运算时,我都会将十六进制转换为整数。这是一个简化的代码。

data = "0x4700ff1de05ca7686c2b43f5e37e6dafd388761c36900ab37"

hex_data = "0x" + data[20:32]
four_bytes = hex_data[:10]
fifth_byte = "0x" + hex_data[10:12]
lshift_fourb = hex(int(four_bytes, 16) << 1)
bitwise_or_res = hex(int(lshift_fourb, 16) | int(fifth_byte, 16))

是否有一种简单的方法可以省略来回转换为整数和十六进制的常量,以便执行相同的操作。我更喜欢使用十六进制或二进制,因为我需要从输入数据字符串中提取某些字节,而hex(int(hex_number, 16)) 似乎有点过于重复和乏味。如果我不将其转换为整数,Python 会抱怨它无法在字符串上执行 |^

【问题讨论】:

  • 将字符串转为整数once,然后在整数域做所有操作,最后只转回字符串once .
  • @mkrieger1 然而,整数不支持切片,因此计算 hex_data 和four_bytes 必须用模数计算。可能,但也很乏味
  • 但我应该如何从整数中提取特定字节?
  • 通过移位和屏蔽。
  • 您还可以编写一些辅助函数来分解重复的内容。

标签: python python-3.x bit-manipulation bitwise-operators


【解决方案1】:

这个怎么样:

data = "0x4700ff1de05ca7686c2b43f5e37e6dafd388761c36900ab37"
size = (len(data)-2)//2
data_bytes = int(data,16).to_bytes(size,byteorder='big')

现在你可以这样做了:

data_bytes[4] & data_bytes[5]

【讨论】:

  • 这似乎有效,但我不知道为什么,当我打印 data_bytes 时,它给了我 b'+C\xf5\xe3~m' 我期待像 b'\x2b\x43\xf5\xe3\x7e\x6d 这样的东西,以及我如何提取前 4 个来自data_bytes 的字节。我也无法对字节和整数执行按位运算,因此我需要将字节转换为整数或将整数转换为字节。
  • 我已经明白为什么data_bytes的格式了,我需要在最后用.hex()打印出来,否则,它正在尝试匹配ASCII码。
  • 我的意思是当我尝试执行 data_byte[3] &lt;&lt; bytes(1) 时,它给了我一个错误,即“字节”对象不支持左移操作。
  • 作为一种解决方法,我需要使用int.from_bytes(data_bytes, byteorder="big") 将字节转换为整数,以便执行按位左移或右移。
  • 至少在我的机器上,打印data_bytes 会产生所需的结果。请注意,我已经编辑了答案中的代码。
【解决方案2】:

正如您所提到的,问题在于十六进制数字字符串更易读,更适合切片和至少一些移位操作,但不支持按位操作。另一方面,整数支持按位运算,但不支持切片。最接近您想要的可能是创建一个实现这两个功能的自定义类(在需要时进行转换)。这不会使您免于实现(和执行)更复杂的代码,但您的应用程序的其余部分可能更具可读性,因为转换是“隐藏的”。

【讨论】:

  • 正是我的观点。十六进制非常适合切片,但我需要一直转换它才能执行按位运算。
猜你喜欢
  • 2014-04-08
  • 2011-07-29
  • 1970-01-01
  • 2019-11-29
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
  • 2011-02-09
  • 2013-05-23
相关资源
最近更新 更多