0

我需要创建两个 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])
    });
}

它返回如下值:

  • 0 --> 0ij7k
  • 1 --> im9ia
  • 2 --> 4q0d0
  • 3 --> mtmnm
  • ...

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

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

4

2 回答 2

1

使用像RC4之类的密码算法(取自此处的代码示例)来加密您的字节,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==

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

于 2021-03-18T16:44:38.620 回答
1

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

这些类型的密码称为格式保留加密(FPE)。一种这样的 FPE 称为 FF1。

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

于 2021-04-08T14:59:01.457 回答