根據用戶量來生成最短的邀請碼


面試提到的需求:根據用戶的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     }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM