我认为这个问题主要是基于意见的,但是,出于安全原因,我已经为我的数据库表的可见ID列创建了自己的Base64 ID生成器(我看到video为什么YouTube会这样做虽然我认为其他安全方式可能并不存在问题,但它仍然有意义。它处理 HIGHLY 不太可能发生重复的事件,但是,我很想知道这是否被用作YouTube视频ID的标准。
Program.cs的
class Program
{
static void Main(string[] args)
{
var ids = new HashSet<string>();
var count = 0; // for testing only
while (count < 8)
{
ids.Add(Base64Id.GenerateId(ids));
Console.ReadLine();
count++; // for testing only
}
}
}
Base64Id.cs
public static class Base64Id
{
private static int IdSize = 1; // Should be 11
private static readonly string[] AllowedChars = {
"0", "1", "2", "3", "4", "5", "6", "7"//,
//"8", "9", "a", "b", "c", "d", "e", "f",
//"g", "h", "i", "j", "k", "l", "m", "n",
//"o", "p", "q", "r", "s", "t", "u", "v",
//"w", "x", "y", "z", "A", "B", "C", "D",
//"E", "F", "G", "H", "I", "J", "K", "L",
//"M", "N", "O", "P", "Q", "R", "S", "T",
//"U", "V", "W", "X", "Y", "Z", "-", "_"
};
private static Random _random = new Random();
/// <summary>
/// To generate a Base64 ID and check to make sure the ID is not already in use.
/// </summary>
/// <param name="usedIds">List of IDs already in use from the Database or other source.</param>
/// <returns>New Base64 ID</returns>
public static string GenerateId(HashSet<string> usedIds)
{
var autoGenId = "";
do
{
autoGenId = "";
for (var i = 0; i < IdSize; i++)
autoGenId += GetRandomChar();
#if DEBUG
_DEBUG_(usedIds.Count() + 1, autoGenId);
#endif
}
while (IsTaken(autoGenId, usedIds));
return autoGenId;
}
private static string GetRandomChar()
{
var i = _random.Next(0, AllowedChars.Length);
return AllowedChars[i];
}
private static bool IsTaken(string id, HashSet<string> usedIds)
{
var check = usedIds.Any(i => id.Contains(i));
if (check)
return true;
return false;
}
private static void _DEBUG_(int count, string id)
{
Console.WriteLine(String.Format("{0}:\t{1}", count, id));
}
}
我相信这对于我的目的来说就像一个魅力,并且没有任何问题,就像在测试期间那样。 然而,一旦我将其缩小到8个字符并且ID大小为长度1,由于在8个预期输出中只有6个发生后不断循环,它会引发严重错误。
我知道这是来自每次被击中的随机数,而且可供选择的次数越少,循环就越可能发生。
我知道如何解决这个问题,但是按照我计划的规模,想到这个很疯狂,例如拥有一个包含所有可能性的数组/列表并删除所选ID。
这是我的问题;
- Youtube之类的人是否知道这个问题,并且由于可能的ID大小而不在乎。
- 他们在课堂上有更多的想法。
- 他们不关心如此高数字的处理成本,并处理每一个小细节。
- 或者他们在代码中使用Base64Encode而不是自动生成它。
醇>
我想知道您对如何改进代码的意见和建议,或者甚至是如此重要的数字。我已经回答了我认为可能的改进方法。
更新
我在周末离开了两个游戏机,一个使用List
,另一个使用HashSet
,处理过的记录之间的差异在另一个层面上。因此,我已将上述代码更改为HashSet
而不是List
,并将代码设置为自动运行。
答案 0 :(得分:1)
我认为,对于可能的ID数量,不需要进行大量的处理,以确保ID是唯一的,因为有 73,786,976,294,838,206,464,它会进一步到达列表的末尾。 可能性。
说十个可能的ID 1 - &gt; 10,如果已经选择了2,那么下一次,它有20%的可能性被复制,如果选择了8,则有80%的几率,每次。使用概率,这将叠加并降低获得唯一ID的机会。
一旦数字很低,这很安静,第一次需要14539279次迭代,第二次需要662984次迭代才能显示所有8个唯一ID。数字越大,我知道要达到这个突破点需要更长的时间,但情况会更糟。
我认为,一旦数字变得更大,可以将其拆分为二叉树,以便充分利用它,一旦说每个块几十万或百万达到50%或60%的使用,忘记其余的和进入下一个范围。
我认为这可能是尝试加速处理可能列表后期阶段的唯一ID的好方法。