php根据id生成10位不重复数字跟字母混合字符串
修改自: Laravel根据用户id生成四位数唯一邀请码
效果
S9q6Cdw9wB
e5D9uS6Lw2
w9G3KIJkwa
Q0F8d6LSwb
M7q3OvSDwC
C8g4MLZ2wD
S8L8d4xGwc
s8f19VIowE
Q5L2SV3bwF
H9W42ctdwG
代码
<?php
namespace App\Services;
// 邀请码服务
class InviteCodeService
{
protected $key,$num,$wordKey,$numericKey;
public function __construct()
{
$this->key = 'X1A3B2abCDcEFGdH4eI5JfK6LgNM7OhP8QiR9SjTkUlVmWnSoYpZqrstuvwxyz';
$this->wordKey = 'AaBbCDcdeEfFgGihHIjJlKknmLqoNrwMpsvsOuPytQRzSTUVWSYZ';
$this->numericKey = '1234567890';
// 注意这个key里面不能出现数字0 否则当 求模=0 会重复的
// 多少进制
$this->num = strlen($this->key);
}
// 传递用户id生成唯一邀请码
public function enCode(int $user_id, $length = 10)
{
$code = $end = $begin = $middle = ''; // 邀请码
//末尾用取模算法保证唯一
while ($user_id > 0) { // 转进制
$mod = $user_id % $this->num; // 求模
$user_id = ($user_id - $mod) / $this->num;
$end = $this->key[$mod] . $end;
}
// 开头使用4位随机的数字加字母
$begin = $this->wordKey[rand(0, strlen($this->wordKey) - 1)] . $this->numericKey[rand(0, strlen($this->numericKey) - 1)] . $this->wordKey[rand(0, strlen($this->wordKey) - 1)] . $this->numericKey[rand(0, strlen($this->numericKey) - 1)];
// 中间用随机字符串补充
while((strlen($begin)+strlen($middle)+strlen($end)) < $length){
$middle = $this->key[rand(0, $this->num - 1)] . $middle;
}
$code = $begin.$middle.$end;
return $code;
}
/**
* 邀请码获取用户id 一般都不需要用到
* 这里的解密代码不完整,思路是对的
* 解密思路
* 加密的时候最后一位记录唯一串的长度,也就是 $end 的长度
* 解密的时候读取串的最后一位获得长度,根据长度获取 $end 字符串
* $end 通过以下函数就能实现解密
* */
function deCode($code)
{
if (strrpos($code, '0') !== false)
$code = substr($code, strrpos($code, '0') + 1);
$len = strlen($code);
$code = strrev($code);
$user_id = 0;
for ($i = 0; $i < $len; $i++)
$user_id += strpos($this->key, $code[$i]) * pow($this->num, $i);
return $user_id;
}
$a = 3600;
$b = $a + 10;
for($i=$a ; $i<$b;$i++){
echo (new InviteCodeService)->enCode($i); echo PHP_EOL;
}
结尾
- 中间四位字符串确保有字符串+数字,
- 尾数6位数确保随机性,6位数足够61^6次方,也就是 51520374361,这个数字比 int(11)表示的最大值 2147483648 还要大 49372890713。5位数就足够覆盖 int(11),剩余一位由开头补充
- 开头补充数字确保够10位
本作品采用《CC 协议》,转载必须注明作者和本文链接
直接用得Hashids 扩展
不是有个uuid 生成的sdk吗Ramsey\Uuid\Uuid