我正在写一篇关于 Guid/UID 的人类可读替代品的小文章,例如在 TinyURL 上用于 url 哈希的那些(通常印在杂志上,所以需要简短)。
我生成的简单 uid 是 - 6 个字符:小写字母 (az) 或 0-9。
“根据我的计算队长”,这是 6 个相互排斥的事件,虽然计算冲突的概率比 P(A 或 B) = P(A) + P(B) 更难,因为显然它包括数字和从在下面的代码中,您可以看到使用 50/50 是使用数字还是字母。
我对冲突率感兴趣,如果下面的代码是您从生成哈希中获得的预期冲突率的真实模拟。平均而言,我每百万次发生 40-50 次冲突,但请记住,uid 不会一次生成一百万次,但可能每分钟只有 10-1000 次左右。
每次发生冲突的概率是多少,有人能提出更好的方法吗?
static Random _random = new Random();
public static void main()
{
// Size of the key, 6
HashSet<string> set = new HashSet<string>();
int clashes = 0;
for (int n=0;n < 1000000;n++)
{
StringBuilder builder = new StringBuilder();
for (int i =0;i < 7;i++)
{
if (_random.NextDouble() > 0.5)
{
builder.Append((char)_random.Next(97,123));
}
else
{
builder.Append(_random.Next(0,9).ToString());
}
}
if (set.Contains(builder.ToString()))
{
clashes++;
Console.WriteLine("clash: (" +n+ ")" +builder.ToString());
}
set.Add(builder.ToString());
_random.Next();
//Console.Write(builder.ToString());
}
Console.WriteLine("Clashes: " +clashes);
Console.ReadLine();
}
更新: 这是这个问题的结果文章
我真的在这里问了两个问题,所以我在作弊。我所追求的答案是 rcar 的,但 Sklivvz 的也是第二部分的答案(另一种选择)。是否可以在数据库中创建一个自定义的唯一 ID 生成器,或者它是客户端(首先是 2 个可能的读取)?
我所追求的一般想法是在数据库或其他可以通过电话或印刷材料使用的商店中使用 ID,而不是巨大的 16 字节 guid。
更新 2:我将公式用于两个互斥事件而不是 2 个独立事件(因为第一次获得“a”并不意味着您第二次无法获得“a”)。应该是 P(A 和 B) = P(A) x P(B)