我正在寻找一种方法,通过顺序用户ID生成一个随机的、唯一的9位好友码(Friend Code)给用户。这样做的想法是为了避免人们通过逐个搜索好友码来枚举用户。如果有1000个可能的代码和100个注册用户,则搜索随机代码应该有10%的几率找到一个用户。
一种可能的方法是随机生成代码,检查代码是否已经被使用,如果已经被使用则重新生成。我正在寻找一种方法(主要是出于好奇心),通过算法生成好友码,并保证第一次尝试时唯一。
具体来说,给定一个数字范围(1到999,999,999),对这个数字运行函数应该返回同一范围内的另一个数字,与输入数字成对且唯一。只有当范围改变和/或随机性的输入种子改变时,这种配对才会有所不同。
理想情况下,个人不应该能够轻松地从好友ID中逆向工程出用户ID,除非知道种子和算法(或者拥有大量的样本和大量时间——这不需要是密钥安全的),因此从最大范围中减去用户ID并不是一个有效的解决方案。
以下是一些C#代码,通过生成整个数字范围、洗牌列表,然后将用户ID作为列表索引来检索好友ID,以实现我的目标:
一种可能的方法是随机生成代码,检查代码是否已经被使用,如果已经被使用则重新生成。我正在寻找一种方法(主要是出于好奇心),通过算法生成好友码,并保证第一次尝试时唯一。
具体来说,给定一个数字范围(1到999,999,999),对这个数字运行函数应该返回同一范围内的另一个数字,与输入数字成对且唯一。只有当范围改变和/或随机性的输入种子改变时,这种配对才会有所不同。
理想情况下,个人不应该能够轻松地从好友ID中逆向工程出用户ID,除非知道种子和算法(或者拥有大量的样本和大量时间——这不需要是密钥安全的),因此从最大范围中减去用户ID并不是一个有效的解决方案。
以下是一些C#代码,通过生成整个数字范围、洗牌列表,然后将用户ID作为列表索引来检索好友ID,以实现我的目标:
int start = 1; // Starting number (inclusive)
int end = 999999999; // End number (inclusive)
Random random = new Random(23094823); // Random with a given seed
var friendCodeList = new List<int>();
friendCodeList.AddRange(Enumerable.Range(start, end + 1)); // Populate list
int n = friendCodeList.Count;
// Shuffle the list, this should be the same for a given start, end and seed
while (n > 1)
{
n--;
int k = random.Next(n + 1);
int value = friendCodeList[k];
friendCodeList[k] = friendCodeList[n];
friendCodeList[n] = value;
}
// Retrieve friend codes from the list
var userId = 1;
Console.WriteLine($"User ID {userId}: {friendCodeList[userId]:000,000,000}");
userId = 99999999;
Console.WriteLine($"User ID {userId}: {friendCodeList[userId]:000,000,000}");
userId = 123456;
Console.WriteLine($"User ID {userId}: {friendCodeList[userId]:000,000,000}");
用户ID 1:054,677,867
用户ID 99999999:237,969,637
用户ID 123456:822,632,399
不幸的是,这对于大范围来说是不合适的 - 这个程序需要8GB的RAM才能运行,如果使用10或12位数字的好友代码,预先生成列表在内存或数据库中都是不可行的。我正在寻找一个不需要这个预生成步骤的解决方案。
我对使用种子随机数生成器或位操作技巧来实现此目的的解决方案感兴趣,如果可能的话。上述函数是可逆的(通过搜索列表的值),但解决方案不需要可逆。