求0至2^256范围内的可逆唯一伪随机映射函数f(n)
实现0到2^256的伪随机双射映射函数
核心思路:简化版Feistel网络
要实现**双射(1对1可逆)**且看似随机的映射,Feistel网络是最优选择之一——它天生具备可逆性,通过简单的轮函数就能生成伪随机输出,完全符合你“无需高破解难度”的要求。
具体实现方案
1. 分块处理
把256位输入n拆分为两个128位的块:L0(高128位)和R0(低128位)。
2. 简易轮函数设计
用轻量的非线性变换作为轮函数,不需要复杂加密算法,比如:
def round_function(R, round_key): # 异或+循环移位+异或的简单非线性组合 temp = R ^ round_key # 128位循环左移17位,避免溢出 temp = ((temp << 17) | (temp >> (128 - 17))) & ((1 << 128) - 1) return temp ^ round_key
这里的round_key用几个固定的128位常量即可,比如0xdeadbeefdeadbeefdeadbeefdeadbeef,因为不需要高安全性,固定密钥完全够用。
3. 多轮Feistel变换
执行3-4轮变换就能达到足够的伪随机效果:
- 每一轮规则:
Li = R(i-1),Ri = L(i-1) ^ 轮函数(R(i-1), 当前密钥) - 轮次结束后,拼接最终的
Ln和Rn就是输出f(n)。
4. 逆函数实现
Feistel网络的逆变换极其简单:只需反向遍历轮密钥,用同样的轮函数逆向计算即可,每一步的可逆性天然保证了整体能还原出原始输入。
代码示例(Python)
# 固定轮密钥(128位) ROUND_KEYS = [ 0xdeadbeefdeadbeefdeadbeefdeadbeef, 0xcafebabecafebabecafebabecafebabe, 0x123456789abcdef0123456789abcdef0 ] def round_function(R, key): temp = R ^ key temp = ((temp << 17) | (temp >> (128 - 17))) & ((1 << 128) - 1) return temp ^ key def f(n): mask_128 = (1 << 128) - 1 # 拆分256位为高低128位 L = (n >> 128) & mask_128 R = n & mask_128 for key in ROUND_KEYS: new_L = R new_R = L ^ round_function(R, key) L, R = new_L, new_R # 拼接结果返回 return (L << 128) | R def f_inv(m): mask_128 = (1 << 128) - 1 L = (m >> 128) & mask_128 R = m & mask_128 # 反向遍历轮密钥实现逆变换 for key in reversed(ROUND_KEYS): new_R = L new_L = R ^ round_function(L, key) L, R = new_L, new_R return (L << 128) | R # 验证双射性 test_n = 0x123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0 test_m = f(test_n) assert f_inv(test_m) == test_n print("双射验证通过")
方案优势
- 双射保证:Feistel每一轮变换都可逆,整体必然是1对1映射,不会出现碰撞。
- 伪随机效果:多轮非线性变换后,输出与输入无明显关联,满足“随机打乱”需求。
- 可逆简单:逆函数仅需反向执行轮变换,实现成本极低。
- 低破解难度:轮函数和密钥都公开且简单,只要知道实现逻辑就能轻松破解,符合要求。
内容的提问来源于stack exchange,提问作者Bananenkris
相关产品推荐
相关产品推荐

