从0到M的整数将映射到由特定字母组成的n字符代码。 棘手的部分是代码应该看起来是伪随机的,非顺序的。像这样:
0 BX07SU
1 TYN9RQ
2 QZ1697
我认为这是我想念的常识。他们如何调用这种类型的函数f(i) = s
- 它将整数映射到伪随机字符串,在一定范围内没有碰撞?
反向函数也很棒:h(s) = i
,能够将有效字符串“解码”回整数,或者确定提供的字符串无效。
答案 0 :(得分:4)
对于小M
@ user1494736是正确的:只需创建一个恰好是双射的查找表,并根据您的需要进行定制。
对于大M
存储表格变得不切实际;我们需要一种算法来计算映射。你提到我们不需要强大的加密技术;这使我们可以选择比标准密码更轻量级的东西。也就是说,它们非常快,我希望你可以轻松地使用第三方库。但是我们假设你更愿意出于某种原因避免这种情况。
制作穷人密码的一种方法是将xor
一个常数放到你的明文上(改变汉明重量),然后应用一点排列(以破坏局部性)。这两个步骤都是可逆的。听起来你想要将密码字母显示为ASCII。因此,我们可能需要最终的可逆变换(加法)以确保密码值是可打印的。
你提到M
可能有几百万。所以,让我们把你的明文字母(以及密文字母)作为32位值。找到一个随机的32位值到xor
很容易。比特排列怎么样?
几百万个明文字母转换成每个字母大约22
或23
位宽;这使得每个明文字母中至少清除8
(逻辑)高位。置换可以利用这一点来帮助确保密文字节在ASCII可打印范围内。通过将上部明文字节发送到四个密码字节中的每一个的高位两位,我们确保每个密码字节取值0
到63
。然后,最后一步可以添加48
以使范围48
变为111
,完全在ASCII可打印范围内。
根据这一观察结果,我们可以将我们的明文字母设想为4x4
位对的网格,并使我们的排列成为该网格的旋转:
Plain
A B C D byte 3 (the high byte, expected to be all 0)
E F G H byte 2
I J K L byte 1
M N O P byte 0
Cipher
D H L P byte 3
C G K O byte 2
B F J N byte 1
A E I M byte 0
或换句话说:
Byte 3 2 1 0
Plain ABCD EFGH IJKL MNOP
Cipher DHLP CGKO BFJN AEIM
请注意,每个明文字节中都会出现一个明文字节:这将确保编码“看起来随机”。
答案 1 :(得分:1)
对于related question,我发了一个答案。在您的情况下,您需要一个额外的数学函数来将您的数字映射到不同的数字(可能使用简单的哈希函数),并使用将此数字编码为基数为36的数字。
答案 2 :(得分:0)
获得单向双射哈希的最简单方法是使用普通的旧CRC。对于32/64位,它是可逆的,但我从未见过要反向执行的代码。