生成唯一随机码的方法及优缺点分析
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
⽣成唯⼀随机码的⽅法及优缺点分析
现在的WEB中经常会需要产⽣⼀些邀请码、激活码。
需要是唯⼀并且随机的。
下⾯总结⼀些常⽤的产⽣随机码的⽅法
从⽹络上采集了⼀些思路,做⼀下分析。
1. ⾃⼰写代码产⽣随机的数字和字母组合,每产⽣1个去查询该随机码是否已存在,如果已存在,则重新产⽣,直到不重复为⽌。
优点:没发现有啥优点。
缺点:产⽣速度慢,数据库交互频繁。
2. guid,该⽅法应该是⽤的⽐较多的。
优点:使⽤简单⽅便,不⽤⾃⼰编写额外的代码
缺点:占⽤数据库空间相对较⼤,特别是根据guid查询速度⽐较慢(毕竟是字符串)。
3. 主键+随机码的⽅式,我们产⽣的随机码保存到数据库肯定会有个主键,⽤该主键+随机字符来组合。
产⽣步骤:
1) 先从id⽣成器中获取id,⽐如是155.
2)填充成固定位数(⽐如8位)的字符串(不够位数的左边填0,超过位数直接使⽤该数字),得到:00000155
3)在每个数字后⾯随机插⼊1个字母或其它⾮数字符号,得到:0A0F0R0Y0H1K5L5M
这样就可以得到1个随机的唯⼀的邀请码了。
优点:使⽤也⽐较简单,不⽤查询数据库。
最⼤的优点是查询的时候,可以根据邀请码直接得到主键id,
然后根据id去数据库查询(速度很快),再⽐较查询出来的邀请码和⽤户提交的邀请码是否⼀致。
缺点:需要使⽤id产⽣器,如果主键是数据库⾃增长的就不太好⽤(需要先进⼊数据库获取id,再更新邀请码)。
4. 有时候产品经理说,我要求邀请码都是数字的。
why?no why? 我喜欢。
1) 获取id: 155
2) 转换成8进制:233
3) 转为字符串,并在后⾯加'9'字符:2339
4)在后⾯随机产⽣若⼲个随机数字字符:233967524987
转为8进制后就不会出现9这个字符,然后在后⾯加个'9',这样就能确定唯⼀性。
最后在后⾯产⽣⼀些随机数字就可以。
优缺点同⽅法3
5.根据各路神仙的⽅法,构造⼀个看起来更像随机码的伪随机码
1)随机⼀个数字+字母组合的随机码:U5Z1SG
2)获取id:155
3)转换成字符串,补齐长度到6位,补齐的字符使⽤⾮数字字符,可已在前⽅或者后⽅补齐(我这⾥是补在后⾯):155XSF 4)把两个字符串连接在⼀起:U5Z1SG155XSF
这个字符串是不是更想⼀个随机码了?
优缺点与⽅法3同理
来看看⽅法5的实现⽅法(以PHP为例)
/*
补位函数,使⽤⽅法:DispRepair('getstr',repaircode_length,'fillstr','type')
功能:补齐字符串长度
$gstr:原字符串
$newlen:新字符串长度
$fill:补位字符集,不能出现唯⼀标识中可能出现的字符
type:类型,1为前补,其他值为后补
*/
function DispRepair($gstr,$disrepairlen,$fillstr,$type) {
$length = $disrepairlen - strlen($gstr);//需要补齐的字符串长度
if($length<1){
return$gstr;
}else{
$newstr = "";//创建新字符串
//要补齐的字符串,每⼀位都随机⼀次
for ( $i=0; $i < $length; $i++ ){
$newstr .= $fillstr[mt_rand(0,strlen($fillstr)-1)];//组装新字符串
}
if ($type == 1) {
$gstr = $newstr.$gstr;//将新字符串填充到原字符串前⽅
} else {
$gstr .= $newstr;//将新字符串填充到原字符串后⽅
}
}
return$gstr;
}
/*
*建码函数,使⽤⽅法:CreateCoupon ("id",code_length,repaircode_length)
*功能:⽣成带唯⼀标识的伪随机码
*$newid:int 唯⼀标识符
*$newcodelen:int 第⼀段码值长度
*$newdisrepairlen:int 第⼆段码值长度
*/
function CreateCoupon ($newid,$newcodelen,$newdisrepairlen){
$codelen = $newcodelen;
$id = $newid;
$disrepairlen = $newdisrepairlen;
$charset0 = 'ABCDEFGHKMNPRSTUVWXYZ23456789';//第⼀段随机码字符集,数字1,0与字母I,l,O过于形似,字符集中排除了这些字符
$charset = 'ABCDEFGHKMNPRSTUVWXYZ';//补齐码值的字符集,ID为10进制,字符集中不能出现数字[0-9],否则最终的字符串可能出现重复(尽管前半段与后半段同时重复的概率很低)$_len = strlen($charset0)-1;//字符集最⼤序号
$coupon = "";//创建随机码变量
//创建⼀个随机码,每⼀位都随机⼀次
for ($i=0;$i<$codelen;$i++) {
$coupon .= $charset0[mt_rand(0,$_len)];
}
$nid = DispRepair($id,$newdisrepairlen,$charset,"0");//调⽤补位函数补齐特征字符串,防⽌券码出现重复,⾮1为后补
$coupon .= $nid;//组装成完整的随机码
return$coupon;
}
CreateCoupon("155",6,6);
我把补位与建码分成了两个函数进⾏封装,看起来有点⼉乱,⼤神些有什么见解欢迎指点。