我想知道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;
}