统计脑筋搜索器:如何创建随机唯一的6位数PIN并分发以最小化概率冲突

时间:2013-07-22 19:14:09

标签: php statistics probability probability-theory probability-density

我想创建一个脚本,用户可以在注册电子邮件后使用该脚本生成图钉。引脚需要长6位且唯一;没有两个用户可以拥有相同的引脚。

我有以下代码,但是无法在无限循环中陷入困境。随着使用更多引脚,循环while()函数的概率增加。有没有人知道更优雅的解决方案?

用户使用其引脚从网站访问免费服务。如果用户猜到另一个引脚,则服务没有失败,但会破坏用户体验。

如果可能的话,我想以这样的方式分发PIN,从统计上来说,猜测引脚的可能性是可以忽略的。

<?php
if($_POST['srSubmit'] && $_POST['srEmail'] && $_POST['srPass']) {
    $conn = mysqli_connect('localhost','root','','db_test');
    while(1) {
        $pin = rand(111111,999999);
        $sel = mysqli_query($conn,"SELECT * FROM formusers WHERE pin = '$pin'");
        if(mysqli_num_rows($sel) != 0) {    continue; }

        mysqli_query($conn,"INSERT INTO formusers(email,password,pin) VALUES('".$_POST['srEmail']."','".$_POST['srPass']."','".$pin."')");
        if(mysqli_affected_rows($conn)!=-1)  {
            echo "Pin:" . $pin;
            exit;
        } else {
            echo "Existing email, try again<br />";
        }
        break;
    }

}
?>
<form method="POST" action="">
<input type="email" name="srEmail" value="" placeholder="Email" /><br />
<input type="password" name="srPass" value="" placeholder="Password" /><br />
<input type="submit" name="srSubmit" value="Register" />
</form>

1 个答案:

答案 0 :(得分:0)

我同意一些您可能想重新考虑您的方法的评论者。但是,如果您决定接受它,并且如果您根据数值距离解释接近度(例如,与Levenshtein距离相反),那么您可以考虑使用Halton sequence或其他准随机序列。来自维基百科:

  

Halton序列是根据确定性方法构建的   使用素数作为基础。举个简单的例子,我们来看看吧   Halton序列的一个维度基于2和另一个维度   3.要生成2的序列,我们首先将间隔(0,1)除以一半,然后是四分之一,八分之一等,生成

     

1 / 2,1 / 4,3 / 4,1 / 8,5 / 8,3 / 8,7 / 8,1 / 16,9 / 16,......

要将此想法应用于您的情况,只需将序列乘以您的最大PIN并发言。在您实际开始填充空间并均匀分散PINS之前,此方法不会产生冲突。只要您的用户数远远少于您的PIN数量,用户就很难随机猜测其他用户的个人识别码,但如果有人发现您正在使用的序列,他们当然可以重现整个列表。