讨论数量:
我的會員編號直接從9位數開始固定一個起始值 字段類型設置為bigint
public function generateUserNo(): int
{
// 先查詢redis是否存在key
// 如果存在 則使用key的值進行+100-200之間的隨機數
// 如果不存在 則查找最新一筆會員編號值 +100-200 存入到redis
// 如果不存在會員 則使用初始值:127347943
$script = <<<LUA
local val = redis.call('GET', KEYS[1])
if val ~= false then
val = val + ARGV[2]
else
val = ARGV[1] + ARGV[2]
end
redis.call('SET', KEYS[1], val)
return val
LUA;
// 這一步可以做優化 不用每註冊一個用戶都去查一次最後編號
$no = User::getLatestNo() ?? 127347943;
return (int)redis()->eval($script, 1, 'latest_user_no', $no, mt_rand(100, 500));
}
$number = 123;
$length = 9; // 补全后的总长度
// 将数字转换为字符串,因为str_pad()需要字符串作为输入
$numberAsString = (string) $number;
// 使用str_pad()在左侧补全0
$paddedNumber = '1'.str_pad($numberAsString, $length, '0', STR_PAD_LEFT);
echo $paddedNumber; // 输出 "1000000123"
简单点 别想的太复杂
goalng版本
package code
import "strings"
const (
BASE = "A1B2C3D4E5F6G7H8I9JKLMNPQRSTUVWXYZ"
DECIMAL = 34
PAD = "0"
LEN = 10
)
// id转code
func Encode(uid uint64) string {
id := uid
mod := uint64(0)
res := ""
for id != 0 {
mod = id % DECIMAL
id = id / DECIMAL
res += string(BASE[mod])
}
resLen := len(res)
if resLen < LEN {
res += PAD
for i := 0; i < LEN-resLen-1; i++ {
res += string(BASE[(int(uid)+i)%DECIMAL])
}
}
return res
}
func Decode(code string) uint64 {
res := uint64(0)
lenCode := len(code)
baseArr := []byte(BASE) // 字符串进制转换为byte数组
baseRev := make(map[byte]int) // 进制数据键值转换为map
for k, v := range baseArr {
baseRev[v] = k
}
// 查找补位字符的位置
isPad := strings.Index(code, PAD)
if isPad != -1 {
lenCode = isPad
}
r := 0
for i := 0; i < lenCode; i++ {
// 补充字符直接跳过
if string(code[i]) == PAD {
continue
}
index, ok := baseRev[code[i]]
if !ok {
return 0
}
b := uint64(1)
for j := 0; j < r; j++ {
b *= DECIMAL
}
res += uint64(index) * b
r++
}
return res
}
uid可以转为唯一的字符串,字符串也可以反解uid,仅供参考
php版本
<?php
namespace Code;
class EncoderDecoder
{
const BASE = "A1B2C3D4E5F6G7H8I9JKLMNPQRSTUVWXYZ";
const DECIMAL = 34;
const PAD = "0";
const LEN = 10;
public static function encode($uid)
{
$id = $uid;
$mod = 0;
$res = "";
while ($id != 0) {
$mod = $id % self::DECIMAL;
$id = (int)($id / self::DECIMAL);
$res .= self::BASE[$mod];
}
$resLen = strlen($res);
if ($resLen < self::LEN) {
$res .= self::PAD;
for ($i = 0; $i < (self::LEN - $resLen - 1); $i++) {
$res .= self::BASE[($uid + $i) % self::DECIMAL];
}
}
return $res;
}
public static function decode($code)
{
$res = 0;
$lenCode = strlen($code);
$baseArr = str_split(self::BASE);
$baseRev = array_flip($baseArr);
$isPad = strpos($code, self::PAD);
if ($isPad !== false) {
$lenCode = $isPad;
}
$r = 0;
for ($i = 0; $i < $lenCode; $i++) {
if ($code[$i] == self::PAD) {
continue;
}
$index = $baseRev[$code[$i]];
if ($index === null) {
return 0;
}
$b = 1;
for ($j = 0; $j < $r; $j++) {
$b *= self::DECIMAL;
}
$res += $index * $b;
$r++;
}
return $res;
}
}
// 例子
$uid = 123456789;
$encoded = EncoderDecoder::encode($uid);
$decoded = EncoderDecoder::decode($encoded);
echo "Original UID: $uid\n";
echo "Encoded: $encoded\n";
echo "Decoded: $decoded\n";
?>
翻译来自chatgpt
我的會員編號直接從9位數開始固定一個起始值 字段類型設置為bigint
public function generateUserNo(): int
{
// 先查詢redis是否存在key
// 如果存在 則使用key的值進行+100-200之間的隨機數
// 如果不存在 則查找最新一筆會員編號值 +100-200 存入到redis
// 如果不存在會員 則使用初始值:127347943
$script = <<<LUA
local val = redis.call('GET', KEYS[1])
if val ~= false then
val = val + ARGV[2]
else
val = ARGV[1] + ARGV[2]
end
redis.call('SET', KEYS[1], val)
return val
LUA;
// 這一步可以做優化 不用每註冊一個用戶都去查一次最後編號
$no = User::getLatestNo() ?? 127347943;
return (int)redis()->eval($script, 1, 'latest_user_no', $no, mt_rand(100, 500));
}
/**
* 生成邀请码
*/
function get_invite_code($length = 8): string
{
$codeAlphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$token = '';
for ($i = 0; $i < $length; ++$i) {
$token .= $codeAlphabet[mt_rand(0, strlen($codeAlphabet) - 1)];
}
return $token;
}
/**
* 生成卡号
* @param int|string $userId 用户 ID
* @return string
*/
function generate_card_no($userId): string
{
do {
$cardNo = sprintf('%d%02d%d', date('ymd'), random_int(0, 99), substr((string) $userId, -1));
} while (User::query()->where('card_no', $cardNo)->exists());
return $cardNo;
}
dd(generate_card_no(123));
// 240221533
日期六位,随机数两位,再加一位用户 ID,参考淘宝订单号生成规则,最后需要判断一下是否有重复的卡号
推荐文章: