按位异或(XOR)详解
按位异或是二进制位运算的一种,符号是 ^,是编程中非常常用的基础运算。
1 核心规则(记住这 4 条)
两个二进制位相同为 0,相异为 1:
0 ^ 0 = 01 ^ 1 = 00 ^ 1 = 11 ^ 0 = 1
2 计算示例
我们用十进制数字 5 ^ 3 举例:
-
转二进制:
- 5 →
101 - 3 →
011
- 5 →
-
按位异或:
101
^ 011
------
110
-
转回十进制:
110→ 6所以:5 ^ 3 = 6
3 3 个重要特性(面试 / 刷题必用)
-
归零律:任何数和自己异或 = 0
a ^ a = 0 -
恒等律:任何数和 0 异或 = 自己
a ^ 0 = a -
交换律 + 结合律
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)

4.2 交换两个变量(不用临时变量)
代码
# ==========交换两个变量(不用临时变量)==========
a = 10
b = 5
a = a ^ b
b = a ^ b
a = a ^ b
print(f"a: {a}, b: {b}")

原理
用按位异或交换两个变量,核心就是利用它的三条性质:
-
归零律:任何数和自己异或 = 0
a ^ a = 0 -
恒等律:任何数和 0 异或 = 自己
a ^ 0 = a -
交换律 + 结合律
a ^ b = b ^ a(a ^ b) ^ c = a ^ (b ^ c)
一步步拆开算:
设初始:a = A,b = B
第 1 步:a = a ^ b
- 新
a = A ^ B b还是B
第 2 步:b = a ^ b
代入当前值:
b = (A ^ B) ^ B- 根据
x ^ x = 0:b = A ^ (B ^ B) = A ^ 0 = A
现在:
a = A ^ Bb = A
第 3 步:a = a ^ b
代入:
a = (A ^ B) ^ A- 交换律:
a = (A ^ A) ^ B = 0 ^ B = B
最终:
a = Bb = A
总结
利用异或:
- 自己异或变 0
- 0 异或不变
从而把两个数 “揉在一起再拆开”,实现交换。
[!note] 注意
- 只适用于整数
- 可读性差,实际开发一般用临时变量更清晰
- 面试常考,懂原理就行
4.3 简单加密
原理
明文 ^ 密钥 = 密文
密文 ^ 密钥 = 明文
加密解密用的是同一个操作、同一个密钥。
为什么能加密?
异或的规则是:
- 相同为 0
- 不同为 1
再加上两个关键性质:
a ^ 0 = a(跟 0 异或不变)a ^ a = 0(跟自己异或变 0)
所以:
- 加密:
明文 ^ 密钥 = 密文 - 解密:
密文 ^ 密钥 = 明文 ^ 密钥 ^ 密钥 = 明文 ^ 0 = 明文
加密和解密完全对称,这就是 “异或加密”。
优点
- 速度极快(CPU 原生位运算)
- 实现超级简单,几行代码搞定
- 加密解密同一个逻辑
缺点(非常重要)
- 密钥不能重复使用
如果你用同一个密钥加密两条消息,攻击者可以通过密文 ^ 密文 = 明文 ^ 明文,把密钥消掉,直接还原内容。 - 没有扩散性,一位变只影响一位
真实用途
-
简单的防明文存储
比如不想让配置文件里的密码直接裸奔,简单异或一下。
-
嵌入式、低性能设备
算力弱、资源少,用不了 AES 这些复杂算法。
-
简单的通信混淆
防抓包一眼看懂,不防专业的破解。
-
很多简单验证码、小游戏数据保护会用它。
例子
假设:
- 明文:
A - 密钥:
5
- 把 A 转成 ASCII:
65→ 二进制1000001 - 密钥 5 → 二进制
0000101 - 异或加密:
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)

总结
异或加密就是:
用密钥把明文 “打乱”,再用同一个密钥 “恢复回来”。
简单、高效、不安全,适合轻量级混淆,不适合真正的敏感数据。
4.4 总结
- 按位异或:相同为 0,不同为 1,符号
^ - 核心口诀:自己异或为 0,0 异或不变
- 最常用:找唯一出现一次的数字、交换变量、简单加密

浙公网安备 33010602011771号