根据用户量来生成最短的邀请码

面试提到的需求:根据用户的ID和字符串的组合来生成较短的邀请码,还有就是根据这个邀请码解析出邀请码对应的用户ID;生成这样的邀请码我们就不放在数据库里面了,在用户量很大的情况下,对于性能是一个很大的提升。

我错误的设计方案:

 

方案一:随机生成一个字符串在和用户ID做拼接,首先这样的想法就是错的,如果是在这样生成的,别人也会拿到用户的ID,这个时候我们的数据就不安全;还有一点不满足需求,需求说邀请码尽可能短。

方案二:我们将我们的用户id,按照一定的规则插入到随机字符串,比如隔一个字符或或者两个字符插入,这样可以解决方案一安全的问题,但是长度的问题是不能解决的,这个方案又死了;

后面我也没有想到什么方案去解决,面试就死了。

 

正确的方案:

因为当时面试时间短,没有考虑的很详细。后面我查了一些资料,看过之后我就想当时怎么这么菜,因为十进制的数据肯定长,但是我们的十六进制,相对十进制是很短的;这个时候看到一篇文章上面的思路是将用户的ID转换为10+26=36进制的数不就可以了嘛

 1 function createCode($user_id)
 2 {
 3     static $source_string = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
 4     $num = $user_id;
 5     $code = '';
 6     while($num)
 7     {
 8         $mod = $num % 36; 
 9         $num = ($num - $mod) / 36;
10         $code = $source_string[$mod].$code;
11     }
12     return $code;
13 }
邀请码保证了唯一性,并且长度不会太长,用户id也能够根据邀请码反推出来,但是有一点不好的是,别人也可以根据邀请码去反推出user_id,因此,我们需要做一些优化。

优化

把0剔除,当做补位符号,比如小于四位的邀请码在高位补0,这样36进制就变成了35进制,然后把字符串顺序打乱,这样,在不知道$source_string的情况下,是没办法解出正确的user_id的。
 1 //生成邀请码
 2     function createCode ($user_id)
 3     {
 4         static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
 5         $num = $user_id;
 6         $code = '';
 7         while ($num > 0) {
 8             $mod = $num % 35;
 9             $num = ($num - $mod) / 35;
10             $code = $source_string[$mod].$code;
11         }
12         if(empty($code[3])){
13             $code = str_pad($code, 4, '0', STR_PAD_LEFT);
14         }
15         return $code;
16     }
这样,对应user_id的唯一邀请码就生成了,再附一个解码函数:
 1 //解析邀请码
 2     function deCode ($code) 
 3     {
 4         static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
 5         if (strrpos($code, '0') !== false){
 6             $code = substr($code, strrpos($code, '0')+1);
 7         }
 8         $len = strlen($code);
 9         $code = strrev($code);
10         $num = 0;
11         for ($i=0; $i < $len; $i++){
12             $num += strpos($source_string, $code[$i]) * pow(35, $i);
13         }
14         return $num;
15     }
posted @ 2018-08-31 14:47  努力的九月  阅读(2285)  评论(0编辑  收藏  举报