如何在Python中迭代每个字节的每个位?

huangapple go评论81阅读模式
英文:

How to iterate over each bit of a byte in Python?

问题

让我们假设 a=0xF0b=[a的位列表]。我如何迭代遍历a的每个位,以便我可以执行位运算,将该位与列表b中的位进行位运算?

我已尝试使用bin()方法将a转换为其二进制形式,然后循环遍历它,但由于a的每个位现在都是字符串数据类型,因此无法再执行位运算。

任何帮助都将不胜感激!

英文:

Let's say a=0xF0 and b=[a list of bits]. How do I iterate over each bit of a so that i can perform a bitwise operation between that bit and a bit in list b?

I have tried converting a to its binary form using the bin() method before looping through it, however, i can no longer perform a bitwise operation as each bit of a is now of the string datatype.

Any help is appreciated!

答案1

得分: 0

你可以使用位移操作:

a = 0xF0
b = [1, 0, 1, 0, 1, 0, 1, 0]

print(bin(a))
# 0b11110000
for idx, bit_in_b in enumerate(b):
    bit_in_a = (a >> idx) & 1
    binary_and_operation = bit_in_a & bit_in_b
    print(bit_in_a, binary_and_operation)

# 0 0
# 0 0
# 0 0
# 0 0
# 1 1
# 1 0
# 1 1
# 1 0

注意两点:

  • a 从右到左迭代,b 从左到右迭代,但根据需要可以更改。
  • 如果 len(b) 不等于 a 中的比特数,行为可能不是你想要的。
英文:

You can use bitshift:

a = 0xF0
b = [1, 0, 1, 0, 1, 0, 1, 0]

print(bin(a))
# 0b11110000
for idx, bit_in_b in enumerate(b):
    bit_in_a = (a >> idx) & 1
    binary_and_operation = bit_in_a & bit_in_b
    print(bit_in_a, binary_and_operation)

# 0 0
# 0 0
# 0 0
# 0 0
# 1 1
# 1 0
# 1 1
# 1 0

Careful to 2 points:

  • a will be iterated from right to left and b from left to right, but you can change that as needed.
  • if len(b) != number of bits in a, behavior might not be what you want.

答案2

得分: 0

一种简短的表达方式如下
```python
bin(int("".join([str(bit) for bit in b]), 2) ^ a)[2:].zfill(max(len(b), (len(bin(a)) - 2)))

它的工作原理如下:

  • "".join([str(bit) for bit in b]) 将您的列表转换为字符串
  • int(..., 2) 转换为二进制数字
  • ^ 是按位异或运算(或者任何其他您想要的操作)
  • bin(...) 将其转换回二进制表示
  • [2:] 去除字符串的 0b 部分
  • .zfil(...) 填充结果的零,直到结果具有与两个输入中较大者相同数量的位数,以防位运算结果以零开头。

示例:

a = 0xF0
b = [0, 1, 1, 1, 0, 0, 1, 0]
result = bin(int("".join([str(bit) for bit in b]), 2) ^ a)[2:].zfill(max(len(b), (len(bin(a)) - 2)))
print(result)

输出:

10000010

<details>
<summary>英文:</summary>

A one-liner would be this:

bin(int("".join([str(bit) for bit in b]), 2) ^ a)[2:].zfill(max(len(b), (len(bin(a))-2)))

It works like so:
- `&quot;&quot;.join([str(bit) for bit in b]` converts your list to a string
- `int(..., 2)` converts to a number in base 2
- `^` is the bitwise `xor` (or any other operation you want)
- `bin(...)` converts it back to a binary representation
- `[2:]` drops the `0b` part of the string
- `.zfil(...)` pads the result with zeroes until the result has the same number of bits as the largest of the two inputs, in case the bitwise result starts with zeroes.

Example:

a = 0xF0
b = [0, 1, 1, 1, 0, 0, 1, 0]
result = bin(int("".join([str(bit) for bit in b]), 2) ^ a)[2:].zfill(max(len(b), (len(bin(a))-2)))
print(result)

Output:

10000010


</details>



huangapple
  • 本文由 发表于 2023年7月13日 16:33:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76677402.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定