W
e
l
c
o
m
e
: )

按位异或(XOR)详解

按位异或是二进制位运算的一种,符号是 ^,是编程中非常常用的基础运算。

1 核心规则(记住这 4 条)

两个二进制位相同为 0,相异为 1

  1. 0 ^ 0 = 0
  2. 1 ^ 1 = 0
  3. 0 ^ 1 = 1
  4. 1 ^ 0 = 1

2 计算示例

我们用十进制数字 5 ^ 3 举例:

  1. 转二进制:

    • 5 → 101
    • 3 → 011
  2. 按位异或:

  101
^ 011
------
  110
  1. 转回十进制:110 → 6

    所以:5 ^ 3 = 6

3 3 个重要特性(面试 / 刷题必用)

  1. 归零律:任何数和自己异或 = 0

    a ^ a = 0

  2. 恒等律:任何数和 0 异或 = 自己

    a ^ 0 = a

  3. 交换律 + 结合律

    a ^ b = b ^ a

    (a ^ b) ^ c = a ^ (b ^ c)

4 最经典用途

4.1 找 “只出现一次的数字”

数组里其他数字都出现两次,只有一个出现一次,直接全部异或就能得到答案:

示例:[1, 2, 1, 3, 2]
1^2^1^3^2 = (1^1) ^ (2^2) ^ 3 = 0^0^3 = 3
from functools import reduce

# ==========找 “只出现一次的数字”==========
l = [1, 2, 1, 3, 2]

# 方法一
res = 0
for num in l:
    res ^= num

print(res)

# 方法二
res1 = reduce(lambda x, y: x ^ y, l)
print(res1)

images/按位异或(XOR)详解/file-20260417165219291.png

4.2 交换两个变量(不用临时变量)

代码

# ==========交换两个变量(不用临时变量)==========
a = 10
b = 5

a = a ^ b
b = a ^ b
a = a ^ b

print(f"a: {a}, b: {b}")

images/按位异或(XOR)详解/file-20260417165627645.png

原理

按位异或交换两个变量,核心就是利用它的三条性质:

  1. 归零律:任何数和自己异或 = 0

    a ^ a = 0

  2. 恒等律:任何数和 0 异或 = 自己

    a ^ 0 = a

  3. 交换律 + 结合律

    a ^ b = b ^ a

    (a ^ b) ^ c = a ^ (b ^ c)

一步步拆开算

设初始:a = Ab = B

第 1 步a = a ^ b

  • a = A ^ B
  • b 还是 B

第 2 步b = a ^ b

代入当前值:

  • b = (A ^ B) ^ B
  • 根据 x ^ x = 0b = A ^ (B ^ B) = A ^ 0 = A

现在:

  • a = A ^ B
  • b = A

第 3 步a = a ^ b

代入:

  • a = (A ^ B) ^ A
  • 交换律:a = (A ^ A) ^ B = 0 ^ B = B

最终:

  • a = B
  • b = A

总结

利用异或:

  • 自己异或变 0
  • 0 异或不变

从而把两个数 “揉在一起再拆开”,实现交换。

[!note] 注意

  • 只适用于整数
  • 可读性差,实际开发一般用临时变量更清晰
  • 面试常考,懂原理就行

4.3 简单加密

原理

明文 ^ 密钥 = 密文

密文 ^ 密钥 = 明文

加密解密用的是同一个操作、同一个密钥

为什么能加密?

异或的规则是:

  • 相同为 0
  • 不同为 1

再加上两个关键性质:

  1. a ^ 0 = a(跟 0 异或不变)
  2. a ^ a = 0(跟自己异或变 0)

所以:

  • 加密:明文 ^ 密钥 = 密文
  • 解密:密文 ^ 密钥 = 明文 ^ 密钥 ^ 密钥 = 明文 ^ 0 = 明文

加密和解密完全对称,这就是 “异或加密”。


优点

  • 速度极快(CPU 原生位运算)
  • 实现超级简单,几行代码搞定
  • 加密解密同一个逻辑

缺点(非常重要)

  • 密钥不能重复使用
    如果你用同一个密钥加密两条消息,攻击者可以通过密文 ^ 密文 = 明文 ^ 明文,把密钥消掉,直接还原内容。
  • 没有扩散性,一位变只影响一位

真实用途

  1. 简单的防明文存储

    比如不想让配置文件里的密码直接裸奔,简单异或一下。

  2. 嵌入式、低性能设备

    算力弱、资源少,用不了 AES 这些复杂算法。

  3. 简单的通信混淆

    防抓包一眼看懂,不防专业的破解。

  4. 很多简单验证码、小游戏数据保护会用它。

例子

假设:

  • 明文:A
  • 密钥:5
  1. 把 A 转成 ASCII:65 → 二进制 1000001
  2. 密钥 5 → 二进制 0000101
  3. 异或加密:
  1000001
^ 0000101
---------
  1000100

结果是 68 → 对应字符 D

所以:

  • A ^ 5 = D(加密)
  • D ^ 5 = A(解密)

只要不知道密钥 5,别人拿到 D 也不知道原来是 A


==========简单加密==========
def xor_crypt(data: bytes, key: bytes) -> bytes:
    """
    使用异或(XOR)对数据进行加密或解密。
    由于异或操作是对称的,加密和解密使用完全相同的函数。
    """
    # 将密钥循环重复至与数据等长,然后逐字节异或
    key_repeated = (key * (len(data) // len(key) + 1))[:len(data)]
    return bytes(a ^ b for a, b in zip(data, key_repeated))


# 示例:加密和解密一段文本
if __name__ == "__main__":
    # 原始明文(字符串需先编码为字节)
    plaintext = "Hello, 异或加密世界!"
    password = "my_secret_key"

    # 转为字节
    data_bytes = plaintext.encode("utf-8")
    key_bytes = password.encode("utf-8")

    # 加密
    encrypted = xor_crypt(data_bytes, key_bytes)
    print("加密后(字节):", encrypted)
    print("加密后(十六进制):", encrypted.hex())

    # 解密(使用完全相同的函数和密钥)
    decrypted_bytes = xor_crypt(encrypted, key_bytes)
    decrypted_text = decrypted_bytes.decode("utf-8")
    print("解密后文本:", decrypted_text)

images/按位异或(XOR)详解/file-20260417174727695.png

总结

异或加密就是:

用密钥把明文 “打乱”,再用同一个密钥 “恢复回来”。

简单、高效、不安全,适合轻量级混淆,不适合真正的敏感数据。

4.4 总结

  1. 按位异或:相同为 0,不同为 1,符号 ^
  2. 核心口诀:自己异或为 0,0 异或不变
  3. 最常用:找唯一出现一次的数字、交换变量、简单加密
posted @ 2026-04-17 21:13  挖掘鱼  阅读(178)  评论(0)    收藏  举报