优惠券兑换码生成算法

需求:  1.用户使用,需要可读性好;

                  2.要满足大量用户的使用,生成的兑换码数据量大;

                     3.要具备唯一性;

                     4.不可重复兑换,验证是否兑换使用过要简便;

                     5.兑换码的规律性不可被轻易猜到,遭到恶性爆刷;

                     6.算法要高效,保证效率;

       可以考虑三种技术:- UUID       - Snowflake   - 自增id;(这三种方式生成的都是数值类型,所以需要转型)

       Base64,Base32;

       除了字母I、O,数字0、1;我们可使用的就有24个字母和8个数字,也就是32个。

       且为了满足可读性,暂定兑换码为10位,也就是10个字符。

       0-31角标对应24个字母和8个数字

        31=11111

       恰好2的五次方为32,将二进制11111转十进制恰好为31

       一个字符是为5个bit,十位字符是为50个bit位

        UUID需要128位,Snowflake需要64位,都不满足,我们选择自增id

       自增id1增加到Integer的最大值,可以达到40亿以上个数字,而占用的字节仅仅4个字节,也就是32bit

       使用自增id技术,并用Base32转码加密,即可

       这时我们满足了123个条件;

       不可重复兑换解决办法,就是给兑换码一个判断该码是否兑换过,而且验证需要简便

1.兑换码存入数据库中,给兑换码增加一个是否兑换状态的字段,直接读取该字段进行验证

优:简单       缺:对数据库操作频繁,压力大。

2.基于BitMap:跟打卡签到是一样的,判断只有两种状态,0、1;每一个自增id对应一个bit位,而且Redis中的BitMap恰好能支持2的32次方个bit位。4294967296

优:简答、高效、性能好          缺:依赖于Redis

       兑换码的规律性不可被轻易猜到,我们自己设计一种算法,模仿参考JWT技术,JWT分为三部分:   Header、Payload、Signature:这个签名是有一个秘钥,结合Header、Payload,利用MD5或者RSA算法生成的。

       模拟这种思路

       自增id是32个bit位 平均分成8份,每份4个bit位

加权求和,得到的就是签名。也就是用密钥给自增id加密获得签名;

为了防止被猜到密钥,加密规律,我们可以准备16组密钥,也就是4个bit位表达的组号,可以随机,值是多少就是第几组密钥,我称之为新鲜值;

32+4=36,剩下的14位表达签名,不足补0;

14个bit位,11111111111111=16383;

序列号加权运算的秘钥表、在这里存储的密钥明显过于大了,4个bit位转10进制最大15,15*1657=24855

签名14个bit位,0011 1111 1111 1111 = 16383,不够存啊,这怎么解释

他不是直接乘的 后面还有异或操作

拼接:签名 + 新鲜值 + 自增id = 50个bit位,转十进制,就是兑换码。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值