兑换码是要给用户使用的,用户需要输入兑换码,因此可读性必须好。
我们的要求:
- 长度不超过10个字符
- 只能是24个大写字母和8个数字:ABCDEFGHJKLMNPQRSTUVWXYZ23456789(没有字母I和数字1,没有字母O和数字0)
- 数据量大:优惠活动比较频繁,必须有充足的兑换码,最好有10亿以上的量
- 唯一性:10亿兑换码都必须唯一,不能重复,否则会出现兑换混乱的情况
- 不可重兑:兑换码必须便于校验兑换状态,避免重复兑换
- 防止爆刷:兑换码的规律性不能很明显,不能轻易被人猜测到其它兑换码
- 高效:兑换码生成、验证的算法必须保证效率,避免对数据库带来较大的压力
做了一个go语言版本,生成的量级num
注意不要超过uint32
的最大值
num
可以采用redis的incr
自增,不过这样生成的速度将受到制约
如果需要重兑校验可以
基于BitMap:兑换或没兑换就是两个状态,对应0和1,而兑换码使用的是自增id.我们如果每一个自增id对应一个bit位,用每一个bit位的状态表示兑换状态,是不是完美解决问题。而这种算法恰好就是BitMap的底层实现,而且Redis中的BitMap刚好能支持2^32个bit位。
其实这个算法就是自增数+随机数结合10进制转2进制,每5位映射成24个大写字母和8个数字。