唯一的短字符实践之靓号

最近有这么一个需求,要给每个用户生成一个唯一的邀请码,用户可以将这个邀请码分享出去,当新用户使用这个邀请码注册登录的时候,就会给邀请者和被邀请者双方发放奖励。

常见的方法有如下几种:

  1. 直接使用用户uid做邀请码,简单直接,就好像其他app中填入邀请者的手机号一样
  2. 对uid做hash生成一串字符串做邀请码,这个主要是为了避免用户的uid泄露,但是要保存用户uid和邀请码的对应关系
  3. 采用对称加密算法加密uid,这样直接根据邀请码就可以解出用户uid,不需要保存uid和邀请码的对应关系了

我们这边的用户uid是纯数字的,共有13位,给这13位uid生成hash或加密的话,结果会较长,不方便用户分享和填写,产品经理限制邀请码长度为6位,同时生成的邀请码中不能要oO1ILl等容易混淆的字符。

我找了一圈,找到一个hashids算法,官网地址在这里https://hashids.org,他有如下特点:

  1. 对于一个输入,有且只有一个输出
  2. 可以根据输出反向解出输入
  3. 对于差异很小的输入,输出差异很大,无法观测规律
  4. 可以自定义salt
  5. 输出的字符串的范围可以自定义
  6. 可以自定义输出的最小长度
  7. 各种语言的实现均有,被大量使用和验证

但是,他有一个明显的缺陷,给定输出字符串的范围的话,他的最小长度的输出个数会有上限。比如给定输出的字符串范围是0-9A-Z,共计36个,指定输出字符串的长度为6,那么大约7900000个输出长度是为6的,在往后,长度就会增加,变成7。

这个缺陷很明显,但是也是没有办法,因为给定范围和长度,这种排列组合总是有限的。

如果能接受这个缺陷,或者预估这个上限可以接受,亦或者可以接受变长的输出,那么这个方案就可以用一下。

最后,再说下,我这边的实际做法:

  1. 使用redis的自增功能incrby,维护一个序列key
  2. 用户每次申请邀请码自增该key,拿到返回值,使用hashids算法生成一个邀请码
  3. 保存用户uid和该邀请码的对应关系到数据库中

最后修改于 2019-01-18