publicfunctiongenerateUserNo(): 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));}
package code
import "strings"const(BASE="A1B2C3D4E5F6G7H8I9JKLMNPQRSTUVWXYZ"DECIMAL=34PAD="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 +=PADfor 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)// 进制数据键值转换为mapfor k, v := range baseArr {
baseRev[v]= k
}// 查找补位字符的位置
isPad := strings.Index(code,PAD)if isPad !=-1{
lenCode = isPad
}
r :=0for i :=0; i < lenCode; i++{// 补充字符直接跳过ifstring(code[i])==PAD{continue}
index, ok := baseRev[code[i]]if!ok {return0}
b :=uint64(1)for j :=0; j < r; j++{
b *=DECIMAL}
res +=uint64(index)* b
r++}return res
}
publicfunctiongenerateUserNo(): 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));}
高认可度评论:
我的會員編號直接從9位數開始固定一個起始值 字段類型設置為bigint
简单点 别想的太复杂
本质就是弄个唯一字符串,位数自己截取就可以
如果外露的话直接拼接肯定不行,一个是长度不一致,另外太好猜了,时间戳+用户id hash吧
goalng版本
uid可以转为唯一的字符串,字符串也可以反解uid,仅供参考
php版本
为什么要用用户id呢
用户id最大位数补前导0?
sprintf("%09d", $uid)
或者就直接用uid
吧,既然是会员号,就要彰显尊贵的前排数字、靓号;我的會員編號直接從9位數開始固定一個起始值 字段類型設置為bigint
试试这个: github.com/vinkla/hashids#use-padd...
日期六位,随机数两位,再加一位用户 ID,参考淘宝订单号生成规则,最后需要判断一下是否有重复的卡号
直接雪花算法生成不就好了
最简单、最简单、最简单的方法
用脚本先提前把卡号生成,并写入表中
等用户注册的时候, 在从表中逐个取出分发给用户即可
twitter 雪花算法
写个定时脚本一次生成一亿,会员id,随机数就行,去重,保存起来,起码能用一年。
用户id+时间戳
自增id,然自增起始值设置个10000000,类似这样的8为会员卡,就不用额外管理这个规则。 或者提前把卡号生成好,去获取
如果需要绝对不重复。bip39 了解一下。一般服务器不间断的生成到地球爆炸都不会有一个重复的
时间戳加随机数,长度太短估计不行的吧
redis 原子递增就可以了呀
提前生成好,随用随取就好了。
1.数据表字段唯一索引 2.搞个定时任务 redis 集合里面提前生成
你想保证绝对唯一的话,直接用订单自增ID才能保证真正唯一,什么算法都说徒增复杂度,浪费性能。先新建订单数据,拿到自增ID。然后对自增ID进行编码,然后修改订单编号字段。
直接使用时间戳,正好10位
直接使用UUID吧
為什麼搞那麼複雜呢,時間戳+隨機數 不就完事了,除非併發厲害,否則按併發數考量同時在線人數生成位數不就 ok了。沒所謂併發的話,直接時間戳就完事,還能知道客戶什麼時候註冊,多方便
Str::random(40);
1000000000+$id
这种卡号一般有以下特点:
可以先根据用户数量级限定一个卡号范围,比如十位数字,可以是
0000000000-9999999999
。限定范围以后,可以使用脚本生成一个
卡号池
。这里可以使用 Redis 的 Set 类型存储。
接下来就是分配卡号逻辑了。使用时,使用 spop 命令随机获取一个卡号即可。
当卡号作废,或者有回收逻辑时,可以使用 sadd 命令重新加回卡号池。