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 协议》,转载必须注明作者和本文链接
reading
白小二
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 4

直接用得Hashids 扩展

11个月前 评论
mengdodo 11个月前
白小二 (楼主) 11个月前

不是有个uuid 生成的sdk吗Ramsey\Uuid\Uuid

10个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!