【发布时间】:2021-06-15 23:42:24
【问题描述】:
我需要创建两个 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?
【问题讨论】:
-
假设您使用 base-64 编码,因此每个符号 6 位。这意味着一个 5 字符的字符串有 30 位。一个整数是 32 位的,那你怎么能得到原来的数字呢?
-
如果你注意到,在我上面写的函数中,整数的第四个字节被丢弃了。因此,可以仅为前 1600 万个整数(2 ^ 24 = 16,777,216)创建函数 f2。换句话说,我对转换太大的数字不感兴趣
-
为了便于处理,使用 25 位而不是 24 位。然后将它们分成 5 个块和 5 位。将每个块的 32 个可能值与每个位置的 chars 数组中的 36 个可能的目标字符(只需省略未使用的 4 个)之间的映射写入。然后在两个方向上来回使用该映射。
-
如果您要创建一个双向编码和解码函数对,其中前向编码的输入中的单个位变化会返回一个急剧变化的输出值,这将是非常困难的将其放入 5 个字符中。您是否考虑过只在问题上投入 80MB 内存并使用实际随机字符串的字典?
-
@El_Merendero 加密算法都会生成字节,你可以根据需要将它们编码成字符串。