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


    面试提到的需求:根据用户的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     }
  • 相关阅读:
    MySQL--自增列持久化问题
    MySQL--”自然键”和”代理键”优缺点
    MySQL--REPLACE INTO更新自增列值引发的异常
    MySQL Inception--原理和注意事项
    MySQL Inception--安装
    MySQL--关联更新
    MySQL--Delete语句别名+LIMIT
    MySQL Disk--SSD 特性
    BootStrap简介
    BootStrap简单使用
  • 原文地址:https://www.cnblogs.com/meichao/p/9565038.html
Copyright © 2020-2023  润新知