思路误区:随机字符串,MD5截取等,这种方法存在一定重复率。需要做唯一验证。

正确思路:
1,唯一性:根据用户ID,生成唯一的对应的邀请码。
2,高进制:高进制可以用更短的字符长度表达更大的数值。
3,理想值:平常用的字符有0-9A-Z,所以比较理想的进制是36进制。
4,可行性:(36进制)ZZZ =(10进制)46655,(36进制)ZZZZ =(10进制)1679615,(36进制)ZZZZZ =(10进制)60466175,(36进制)ZZZZZZ =(10进制)2176782335
    在转成36进制的情况下 4位邀请码已经可以满足绝大部分公司了,能用到6位邀请码的公司屈指可数。
    
5,加强
    5.1,不满4位左补0。
    5.2,如果只是进制转换,是可以逆的,别人可以算出真实的用户ID。解决方法:把表示36进制的字符 0-9A-Z 顺序打乱,正常进制转换后,再用新的字符顺序转换一下,在不知道这个打乱的字符顺序时,就不可能解析出正确的用户id.
    
    
废话不多说,直接上代码。

 



/**
 * 生成自定义36进制对应关系
 * @return type
 */
function invite_code_seed() {
    $str = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $seed = str_split($str);
    $newkeys = array_flip($seed);
    shuffle($seed);
    foreach ($newkeys as $key => $val) {
        $newkeys[$key] = $seed[$val];
    }
    return $newkeys;
}

/**
 * 根据用户ID生成邀请码
 * @param type $id
 * @param type $seed
 * @return type
 */
function create_invite_code($id, $seed) {
    $thirtySix = strtoupper(base_convert($id, 10, 36));
    if (strlen($thirtySix) < 4) {
        $thirtySix = str_pad($thirtySix, 4, 0, STR_PAD_LEFT);
    }
    $code = '';
    for ($i = 0; $i < strlen($thirtySix); $i++) {
        $code .= $seed[$thirtySix[$i]];
    }
    return $code;
}

/**
 * 解析邀请码
 * @param type $code
 * @param type $seed
 * @return type
 */
function decode_invite_code($code, $seed) {
    $thirtySix = '';
    $newkeys = array_flip($seed);
    $_code = strtoupper($code);
    for ($i = 0; $i < strlen($_code); $i++) {
        $thirtySix .= $newkeys[$_code[$i]];
    }
    return base_convert($thirtySix, 36, 10);
}


点赞(3522) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部