
需求:
function genRandomString($len, $t = 0) { $chars = array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "2", "3", "4", "5", "6", "7", "8", "9"); $chars1 = array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"); $chars2 = array("1", "2", "0", "3", "4", "5", "6", "7", "8", "9"); $chars3 = array("A", "B", "C", "D", "E", "F", "G", "O", "H", "I", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"); if ($t == 1) { $charsLen = count($chars1) - 1; shuffle($chars1); $output = ""; for ($i = 0; $i < $len; $i++) { $output .= $chars1[mt_rand(0, $charsLen)]; } } else if ($t == 2) { $charsLen = count($chars2) - 1; shuffle($chars2); $output = ""; for ($i = 0; $i < $len; $i++) { $output .= $chars2[mt_rand(0, $charsLen)]; } } else if ($t == 3) { $charsLen = count($chars3) - 1; shuffle($chars3); $output = ""; for ($i = 0; $i < $len; $i++) { $output .= $chars3[mt_rand(0, $charsLen)]; } } else { $charsLen = count($chars) - 1; shuffle($chars); $output = ""; for ($i = 0; $i < $len; $i++) { $output .= $chars[mt_rand(0, $charsLen)]; } } return $output; }
基本就是金刚葫芦娃,一股脑生成,插入数据库。连判断都没有。虽然重复的概率小,但还是有可能呀。怎么做到一个优秀一点的?
有没有更好的方法?
是防伪码呀 >_<
1 ryd994 2018-03-23 10:11:51 +08:00 via Android 验证码这种使用场景,难道不该上 redis 么?重启就重启,反正丢几个验证码有没什么大事,用户只会怀疑自己打错了 |
2 arron 2018-03-23 10:28:28 +08:00 如果是批量,你就加两个干扰项:time, index 至于放进去怎么变化看需求,可以保证你生成的字符串不会重复。如果是用的时候再生成,那么 time + rand 基本就可以了,保证重复概率低。 |
3 whileFalse 2018-03-23 11:08:44 +08:00 uuid 不行吗 |
4 oott123 2018-03-23 11:41:17 +08:00 via Android 数据库做个唯一性索引,插崩了就重新插一下 |
5 loveCoding 2018-03-23 11:53:43 +08:00 生成的防伪码长度大概在 12~18 位 有可能是纯数字,或者字母+数字 楼上说的 uuid 满足需求的 |
6 DavidNineRoc OP @ryd994 不是验证码,是防伪码 >_< @arron 真的不是验证码,是防伪码 @whileFalse 给客户使用的,就是验证是否是正品的防伪码 @oott123 这个,每次都插入,不如我的第二个方法 * 我想的就只是插入的时候返回 0 或者 1,循环结束计算返回 1 的集合,是否等于要生成的防伪码数量,如果不等于,(这时候,数量级已经下降了很多) * 来一个死循环,一次生成一个插入数据库,知道成功的条数弥补上一次重复的数量,跳出循环。 @loveCoding uuid 肯定不符合要求,长度太长,而且总是英文数字混合的。想要纯数字根本不可能 |
7 prolic 2018-03-23 13:12:45 +08:00 via Android 这需求数字加盐散列不就够了么,信不过 md5 你可以再去一次重 |
8 rrfeng 2018-03-23 13:15:26 +08:00 via Android 防伪: 发出去的存起来 算法自验证 楼上都在说什么... |
9 DavidNineRoc OP |
10 l12ab 2018-03-23 16:30:53 +08:00 via iPhone 类似于卖软件的生成序列号 |
11 LukeChien 2018-03-23 19:56:51 +08:00 via Android 时间戳+aes(时间戳,秘钥) |
12 chinvo 2018-03-23 19:59:41 +08:00 Sonyflake-like 的串号,加上校验位 |
13 DavidNineRoc OP |
14 chinvo 2018-03-23 23:19:44 +08:00 |
15 DavidNineRoc OP @chinvo 看 $chars3,时间戳都有十位了,再加自增?一次生成十万百万级别的,基本就出现重复了 |
16 xml123 2018-03-24 09:25:03 +08:00 via Android 时间戳是唯一的,就算占了全部的位数,也不会重复啊 |
17 DavidNineRoc OP @xml123 你还年轻,来点并发,就会重复了 |