6位全局唯一随机邀请码实现方式

本文介绍了一种高效生成邀请码的方法,通过将用户ID映射为base34编码,实现全局唯一且无需额外资源的邀请码生成方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

很多APP都会为每一个用户生成一个邀请码,用以奖励用户邀请其他人下载注册使用该APP。例如之前的Uber邀请码、现在的西瓜视频邀请码、各种虚拟货币邀请码等等。这些邀请码多是5位或者6位数字和字母的组合,实现中,每一个用户固定一个邀请码,也就是说邀请码全局唯一。且邀请码没有特定的规律,看上去是随机生成的。那么这些邀请码具体是怎么实现的?

邀请码实现方式

我没有做过邀请码类似项目,所以我能想到的简单的做法就是:

  • 设计一个邀请码程序,预先随机生成一定数量数字和字母组合的指定位数的全局唯一的邀请码,存于数据库或者redis中,新注册用户时取一个邀请码跟用户ID绑定,并保存这个绑定关系。
  • 当随机码用完或者快用完时,再生成一些全局唯一的邀请码,存于数据库或者redis,供新注册用户使用。

这个实现的难度不大,但是要耗费数据库或者redis资源,且难点在于每次生成全局唯一随机邀请码,如果不随机那还好,每次顺序生成就行了,如果要随机,那可能每生成一个邀请码都要跟已有的邀请码做判断,是否重复。

那有没有比较讨巧的做法,无须耗费额外资源就能为每一个用户ID生成一个邀请码?我想到的是参照base64\base62的编码方式。举个例子:

比如我们要生成6位的邀请码,格式是:0-9十个数字,加上24个大写字母(除去O、I两个易混淆字母)的组合。

总共是34个字符,6位。那么能生成邀请码总数是:34的6次方,也就是1544804416个。15亿+个邀请码,而我们的用户量一般很难达到15亿,所以足够用。那么余下的工作就是要将每一个用户ID映射到这唯一一个邀请码中来。
一般我们的用户ID都是一个长整型数,ID都是递增分配。所以这里的问题就成了如何将一个长整形ID映射到一个6位的base34编码中。因为6位base34最多能编出15亿个编码,而我们的用户量很少能达到15亿量级。所以假设我们的用户ID都小于1544804416(只要用户量小于15亿,那总有办法将ID映射到小于15亿。万一哪天用户量大于这个数字,那么恭喜你,你已经不需要邀请码了)。所以实现思路如下:
还记得十进制转二进制怎么做的吧?这里的base34实质上就是将10进制转成34进制。实现就很简单了,详见代码。

package main

import(
	"fmt"
	"container/list"
)

var baseStr string = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
var base [] byte = []byte(baseStr)
//1544804416
func Base34(n uint64)([]byte){
	quotient := n
	mod := uint64(0)
	l := list.New()
	for quotient != 0 {
		mod = quotient%34
		quotient = quotient/34
		l.PushFront(base[int(mod)])
	}
	listLen := l.Len()
	if listLen >= 6 {
		res := make([]byte, 0, listLen)
		for i := l.Front(); i != nil ; i = i.Next(){
			res = append(res, i.Value.(byte))
		}
		return res
	} else {
		res := make([]byte, 0, 6)
		for i := 0; i < 6; i++ {
			if i < 6-listLen {
				res = append(res, base[0])
			} else {
				res = append(res, l.Front().Value.(byte))
				l.Remove(l.Front())
			}

		}
		return res
	}

}

我们跑几个数字看看结果

func main(){
    res := Base34(24)
	fmt.Println("===============base:24->", string(res))

 	res = Base34(200441052)
	fmt.Println("===============base:200441052->", string(res))
	res = Base34(1544804416)
	fmt.Println("===============base:1544804416->", string(res))
}

执行结果如下:

===============base:24-> 00000Q
===============base:200441052-> 4DZRX2
===============base:1544804416-> 1000000

反过来拿着邀请码也可以解出对应的数字ID出来,这个代码我就懒得贴出来了,详见我的github

以上这个base34的方法简单高效,可以根据每个用户的ID生成一个邀请码,根据邀请码可以反解出用户ID,无需查表等而外请求。代码中base数组中,可以随机打乱字符的顺序,让产生的验证码也随机一些(但是解码的时候要用相同的base数组)。那么当用户ID大于1544804415的时候,怎么办?
解决方法其实也简单:

  • 生成7位或者更多位邀请码
  • 实在是只能6位,那么增加base数量,比如将小写字母加进来,60个字符,6位,最大数46656000000,460亿个,long long类型的ID可以大于这个数,但是用户量不可能再多了吧。总有办法将每一个用户映射到base60中的一个编码中的。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值