如何实现一个简短的注册邀请码


首先谈一下我的思路,我准备用0-9,A-Z,a-z 共62个字符组成8位邀请码,也就是一个62进制数

无疑会用到进制转换,在此奉上两个进制转换函数

//其它进制转十进制
function NumBinTo($num,$bin=62,$start='0'){
	$str="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	$arr=explode($start,$str);
	$strD=$start."".$arr[1]."".$arr[0];
	$arrD=array_flip(str_split($strD));
	$numArr=(str_split($num));
	$rs=0;
	$count=count($numArr);
	for ($i = 0; $i < $count; $i++) {
		$rs=intval($arrD[$numArr[$i]])*pow($bin,$count-$i-1) + $rs;
	}
	return $rs;
}


//十进制转 其他 进制 $count 返回数据长度 $bin <= 62
function NumToBin($num,$bin=62,$count=0,$start='0'){
	$str="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	$arr=explode($start,$str);
	$strD=$start."".$arr[1]."".$arr[0];
	$arrD=str_split($strD);
	
	$bytelen=$count; //返回字符长度

  $t="";
  $num=intval($num);
	if($num===0)continue;
  while($num>0){
    $t=$arrD[$num%$bin].$t;
    $num=floor($num/$bin);
  }
  $tlen=strlen($t);
  if ($count) {
   	if($tlen%$bytelen!=0){
	    $pad_len=$bytelen-$tlen%$bytelen;
	    $t=str_pad("",$pad_len,$start,STR_PAD_LEFT).$t; //不足一个字节长度,自动前面补充0
	  }
  }
  
  return $t;
}


邀请码的生成数据来源于数据表中的一个自增字段,当然它也是唯一的;为了降低辨识度必须给它进行加密,在此我想到了一个简单的算法,5位(数据)+1位(随机)+2位(排序);5位62进制能够表达最大的数字是:916,132,831,9亿,一般不是大型数据表足够使用了;随机字符用来定义进制的起始,第一位是0?,A?,a?,随机吧;剩下两位就是将5位主数据进行排列组合,43210(5)<62*62 刚好可以

加密函数:

//格式化输出 A+12345+B+C
//B:起始字符 AC:排序规则
function decto_bin_encode($datalist){
	$strD="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  $rand=rand(0,61);
  $start=substr($strD,$rand,1);
	$str_62=NumToBin($datalist,62,5,$start);
	$str_62_arr=str_split($str_62);
  $arr=array('0','1','2','3','4');
	shuffle($arr);//乱序
	//$arr 转十进制
	$sorkStr_10=NumBinTo(implode('',$arr),5);

	$sork_62=NumToBin($sorkStr_10,62,2,"0");
	$sorkArr=str_split($sork_62);
 	$sorkStr=implode('', $arr);
 	$strArr_sork=array();
  $strArr=explode($start, $strD);

	foreach ($arr as $k=>$v) {
 		$strArr_sork[$v]=$str_62_arr[$k];
 	}
	$r_str_62='';
	for ($j = 0; $j < 5; $j++) {
		$r_str_62.=$strArr_sork[$j];
	}
  return $sorkArr[0].$r_str_62.$start.$sorkArr[1];
}




当然这也是可以解密的

function decto_bin_decode($str){
	$strD="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	//获取解码参数
	$key=substr($str,-2,1);
	$arr=explode($key,$strD);
	$strD=$key."".$arr[1]."".$arr[0];
	$arrD=array_flip(str_split($strD));
	//排序参数
	$sorkCode=substr($str,0,1).substr($str,-1,1);
	$sorkCode_10=NumBinTo($sorkCode);
	//转5进制
	$jmNum=NumToBin($sorkCode_10,5,5);
	
	$jmStr=substr($str,1,5);
	
	//还原排序
	$arr=str_split($str);
	$realArr='';
	foreach (str_split($jmNum) as $val) {
		$k=4-intval($val);
		$realArr.=substr($jmStr,$val,1);
	} 
	$idArr=str_split($realArr);
	$rs=NumBinTo($realArr,$bin=62,$key);
	return $rs;
}


测试代码:

$codeStr=decto_bin_encode(5201314);
echo $codeStr."<br>";
echo decto_bin_decode($codeStr);

当然每次运行的结果都可能不一样

ps:第一次写博客,有些地方解释的不足希望谅解,如有疑问欢迎联系讨论

邮箱:wangqing9445@qq.com
QQ:286629445

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值