我使用以下perl代码生成随机字母数字字符串(仅限大写字母和数字),以用作MySQL数据库中记录的唯一标识符。该数据库可能会保持在1,000,000行以下,但绝对现实最大值约为3,000,000。我有2个记录具有相同随机码的危险机会,或者它可能发生的次数非常少吗?我对概率知之甚少(如果从这个问题的性质来看还不是很清楚)并且会喜欢某人的意见。
perl -le 'print map { ("A".."Z", 0..9)[rand 36] } 1..6'
答案 0 :(得分:38)
由于Birthday Paradox,它比您想象的更可能。
有2,176,782,336个可能的代码,但即使只插入50,000行也存在相当高的碰撞机会。对于1,000,000行,几乎不可避免地会发生很多碰撞(我认为平均约为250)。
我运行了一些测试,这是我在第一次碰撞发生之前可以生成的代码数量:
随着代码数量的增加,碰撞将变得更加频繁。
这是我的测试代码(用Python编写):
>>> import random
>>> codes = set()
>>> while 1:
code=''.join(random.choice('1234567890qwertyuiopasdfghjklzxcvbnm')for x in range(6))
if code in codes: break
codes.add(code)
>>> len(codes)
36909
答案 1 :(得分:10)
嗯,你有36 ** 6个可能的代码,大约是20亿。调用此 d 。使用找到here的公式,我们发现 n 代码的碰撞概率大约为
1 - ((d-1)/d)**(n*(n-1)/2)
对于超过50,000左右的任何n,这都非常高。
看起来像一个10个字符的代码的碰撞概率只有大约1/800。所以请选择10个或更多。
答案 2 :(得分:7)
基于http://en.wikipedia.org/wiki/Birthday_paradox#Approximation_of_number_of_people给出的等式,在将大约55,000条记录插入此大小的Universe后,有50%的机会遇到至少一次碰撞:
尝试插入两到六倍的记录几乎肯定会导致碰撞。您需要非随机地分配代码,或使用更大的代码。
答案 3 :(得分:6)
如前所述,生日悖论很可能使这一事件发生。特别是,当问题被视为碰撞问题时,可以确定精确的近似值。设p(n; d)
为至少两个数相同的概率,d
为组合数,n
为路径数。然后,我们可以证明p(n; d)
大约等于:
1 - ((d-1)/d)^(n*(n-1)/2)
我们可以在R中轻松绘制这个:
> d = 2176782336
> n = 1:100000
> plot(n,1 - ((d-1)/d)^(n*(n-1)/2), type='l')
给出了
正如您所看到的,碰撞概率随着试验/行数的增加而迅速增加
答案 4 :(得分:1)
虽然我不知道您想要如何使用这些伪随机ID的具体细节,但您可能需要考虑生成3000000个整数的数组(从1到3000000)并随机混洗它。这将保证数字是唯一的。 请参阅Fisher-Yates shuffle on Wikipedia。
答案 5 :(得分:0)
注意事项:谨防依赖伪随机数生成器质量重要的内置rand
。我最近发现了Math::Random::MT::Auto:
Mersenne Twister是一种快速伪随机数发生器(PRNG),能够向可能耗尽“真正”随机数据源或系统的应用程序提供大量(> 10 ^ 6004)的“高质量”伪随机数据 - 提供的PRNG,例如
rand
。
该模块为rand
提供了替代方案,方便使用。
您可以使用以下代码生成密钥序列:
#!/usr/bin/env perl
use warnings; use strict;
use Math::Random::MT::Auto qw( rand );
my $SEQUENCE_LENGTH = 1_000_000;
my %dict;
my $picks;
for my $i (1 .. $SEQUENCE_LENGTH) {
my $pick = pick_one();
$picks += 1;
redo if exists $dict{ $pick };
$dict{ $pick } = undef;
}
printf "Generated %d keys with %d picks\n", scalar keys %dict, $picks;
sub pick_one {
join '', map { ("A".."Z", 0..9)[rand 36] } 1..6;
}
前段时间,我写过关于limited range of built-in rand
on Windows的文章。您可能不在Windows上,但您的系统可能存在其他限制或陷阱。