从 0 到 M 的整数将被映射到由特定字母组成的 n 个字符代码。棘手的部分是代码应该看起来是伪随机的、非连续的。像这样:
0 BX07SU
1 TYN9RQ
2 QZ1697
我认为这是我想念的常识。他们如何调用这种类型的函数f(i) = s
- 将整数映射到伪随机字符串,在一定范围内没有冲突?
反向函数也很棒:h(s) = i
能够将有效字符串“解码”回整数,或确定提供的字符串无效。
对于小M
的@user1494736 是正确的:只需制作一个恰好是双射的查找表,然后根据您的需要对其进行定制。
对于大型M
存储,表格变得不切实际;我们需要一个算法来计算映射。您提到我们不需要强大的密码学;这使我们可以自由选择比标准密码更轻量的东西。也就是说,它们的速度非常快,我希望您可以通过 3rd-party 库轻松使用它们。但是,假设您出于某种原因更愿意避免这种情况。
制作穷人密码的一种方法是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
请注意,每个明文字节的一部分出现在每个密文字节中:这将确保编码“看起来是随机的”。
对于一个相关的问题,我已经发布了一个答案。在您的情况下,您需要一个额外的数学函数来将您的数字映射到不同的数字(可能使用简单的哈希函数)并使用将此数字编码为基数 36 数字。
获得单向双射散列的最简单方法是使用普通的旧 CRC。它对于 32 / 64 位是可逆的,但我从未见过相反的代码。