如何生成唯一的(永久的)字母数字令牌(仅限4到8位数字)


How to generate unique (forever) alphanumeric tokens (4 to 8 digits only)

我想知道PHP中是否有一种方法可以生成唯一的字母数字(区分大小写)令牌,可以永远唯一而不会发生任何冲突。如果我们从时间戳字符串派生它们,该字符串是10个字符,如:1394452319,这可能是可能的,但我不确定我们是否可以使令牌短至4个字符?如果不可能,则5、6、7,最大为8个字符。因为我想生成用户可读的短令牌。

令牌应该看起来像:1aYc, ZoXq, 3iU9等

我不想向用户显示任何序列。

还有一件事,我的应用程序将被多个用户使用,所以如果两个用户同时单击以生成令牌,PHP应用程序会生成相同的令牌吗(我假设我们使用时间戳来生成令牌)?我们怎样才能避免这个问题呢?

谢谢你的帮助!

这是另一个可以使用的函数

<?php 
    function generateRandomString($length = 8) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
       $randomString .= $characters[rand(0, strlen($characters) - 1)];
    }
    return $randomString;
}
echo generateRandomString();
?>

一种方法是在内部隐藏一个增量(即auto_update) id。然后生成一个散列,表示隐藏序列的id。增加的id消除了冲突问题(即MySQL有一个集成的解决方案)。

您现在需要使用的技巧是一个由两列组成的随机哈希表,它们的值都是n到m,但第二列是随机的。例如

col1 | col2
   1 | 2
   2 | 4
   3 | 5
   4 | 1
   5 | 3

如果您的增量数字是随机排序的,则很容易从中创建散列。只要把可能的字符想象成数字。你明白了吗?

假设你有一个很好的随机数算法,你可以做一个很好的哈希表。然而,也有一种方法可以找到一个算法,随着数字的增加为您提供数字。在这个例子中,它会给你col2 = fn(col1),也就是4 = fn(2)。你所要做的就是把结果重新设计成一个公式否则,您必须先填充表格。

为了让你更深入地了解它的数学原理,想象一个函数,它利用数字的奇数/偶数特征,并将其与加法结合起来。

对于n个数字,每个字符使用62种可能(区分大小写的字母和数字),您有62^n种可能。对于4个数字,有14776336种可能(62^4)。

虽然这听起来很棒,但您可以想象,使用一个预先填充了14776336个id的表并不是最干净的解决方案。

不过,我还是希望这至少能引导我们走向正确的方向。

编辑:我们在math.stackexchange.com上开始了讨论。IT有一些关于如何根据我们的需要创建函数的附加信息。

您可以使用以下内容

<?php
      // chars
     $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-+';
     // convert to array
    $arr = str_split($chars, 1);
    // shuffle the array
    shuffle($arr);
   // array to chars with 8 chars
  echo substr(implode('', $arr), 0, 8);
?>

你可以使用这个函数:

    // RETRUN 24 digit of UNIX ID :
    public function getComplexIDTicket(){  // duplicate method on Rest.php
        $arrAZ1 = range('A','Z');
        $arrAZ2 = range('A','Z');
        $arrAZ3 = range('A','Z');
        $arrs1 = range('A','Z');
        $arrs2 = range('A','Z');
        $arrs3 = range('A','Z');
        $a1 = $arrAZ1[rand(0,25)];
        $a2 = $arrAZ2[rand(0,25)];
        $a3 = $arrAZ3[rand(0,25)];
        $s1 = $arrs1[rand(0,25)];
        $s2 = $arrs2[rand(0,25)];
        $s3 = $arrs3[rand(0,25)];
        $s = $s1.$s2.$s3;
        $t = microtime(true);
        $micro = sprintf("%07d",($t - floor($t)) * 10000000);
        $id = date('ymdHis').strtoupper(dechex(substr($micro,0,7)));
        $id = str_pad($id, 24, $a3.$a2.$a1.$s, STR_PAD_RIGHT);
        // 151106214010 3DDBF0 L D C SM4
        return $id;
    }