0

我想创建一个脚本,用户可以在注册电子邮件后使用它来生成 pin。PIN 码必须是 6 位数长且唯一;没有两个用户可以拥有相同的 pin。

我有以下代码,但是除了陷入无限循环之外,我无法继续前进。随着更多引脚的使用,循环 while() 函数的概率会增加。有没有人对此有更优雅的解决方案的想法?

用户使用他们的 pin 从网站访问免费服务。如果用户猜到另一个密码,服务不会失败,但会破坏用户体验。

如果可能的话,我想以这样一种方式分配 PIN,以便在统计上猜到 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>
4

1 回答 1

0

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

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 数量,用户就很难随机猜测其他用户的 PIN,但是如果有人发现您使用的序列,他们当然可以复制完整的列表。

于 2013-07-25T06:01:52.647 回答