将 int 转换为伪随机字符串,反之亦然

Converting an int to a pseudo-random string and vice versa

我需要创建两个 C# 函数,一个(称为 f1)用于将整数转换为字符串,另一个(称为 f2)用于将该字符串转换为起始整数。这些字符串应该看起来像一组 随机的 5 个字符 (字母和数字)。必须确保至少前 1600 万个整数没有冲突(同一字符串的两个可能的整数)(我对转换太大的数字不感兴趣)。

//Where the "BytesToBase32" function converts a byte array to base 32 ()
string IntToString(int id) {
    byte[] bytes = BitConverter.GetBytes(id);
    return Utils.BytesToBase32(new byte[] {
        (byte)(004 + 145 * bytes[0] + 113 * bytes[1] + 051 * bytes[2]),
        (byte)(166 + 237 * bytes[0] + 010 * bytes[1] + 212 * bytes[2]),
        (byte)(122 + 171 * bytes[0] + 135 * bytes[1] + 020 * bytes[2])
    });
}

它 returns 的值是这样的:

如您所见,字符串似乎是随机的(换句话说,无法理解“0ij7k”出现在“im9ia”之前,反之亦然)。

问题是函数f2不能通过简单求解f1使用的3方程组得到。有没有更简单的方法来获取f1和f2?

使用像 RC4 (code sample taken from here) 这样的密码算法来加密 int 的字节,然后简单地对这些字节进行 Base64 编码以生成字符串可能就足够了。对于任何 int,这将始终是相同的长度。

var pwd = Encoding.UTF8.GetBytes("SomePassword");
var enc = Convert.ToBase64String(RC4.Encrypt(pwd, BitConverter.GetBytes(input)));
var dec = BitConverter.ToInt32(RC4.Decrypt(pwd, Convert.FromBase64String(enc)));

实例:https://dotnetfiddle.net/gK593y

此样本确实存在您的“相邻数字”问题

16: SB8u1Q==
17: SR8u1Q==
18: Sh8u1Q==
19: Sx8u1Q==

我不确定这对您来说有多大问题。

在评论中我对流密码的看法是错误的。您实际上需要一个块密码,但块的大小必须为 24 位(对于 1600 万个整数)。看到这个问题和答案:https://crypto.stackexchange.com/q/18988

这些类型的密码称为 Format-preserving encryption (FPE)。一种这样的 FPE 称为 FF1。

github 上有 FF1 的 C# 实现:https://github.com/a-tze/FPE.Net