数学建模社区-数学中国

标题: PHP生成随机密码的4种方法及性能对比 [打印本页]

作者: 曾经的王者    时间: 2015-4-30 14:14
标题: PHP生成随机密码的4种方法及性能对比
方法一:1、在 33 – 126 中生成一个随机整数,如 35,
1 n/ `5 p& F) v2、将 35 转换成对应的ASCII码字符,如 35 对应 #
6 n3 k+ P& d3 l" _# Q3、重复以上 1、2 步骤 n 次,连接成 n 位的密码0 t2 h$ S7 ^" u6 Q5 d- k
该算法主要用到了两个函数,mt_rand ( int $min , int $max )函数用于生成随机整数,其中 $min – $max 为 ASCII 码的范围,这里取 33 -126 ,可以根据需要调整范围,如ASCII码表中 97 – 122 位对应 a – z 的英文字母,具体可参考 ASCII码表chr ( int $ascii )函数用于将对应整数 $ascii 转换成对应的字符。+ ^/ p5 X9 [4 Z' v% U: Y
view source7 E* i$ K8 k7 g: s) w: _
print?' ~- V% e# v* X" V3 @2 h" i

- C; s  ?# V3 F01.function create_password($pw_length = 8)
3 e' B& l& _9 E; p02.{
. \3 f" X0 b2 q/ ~1 z! }03.    $randpwd = '';/ H7 G, R0 t3 i% \
04.    for ($i = 0; $i < $pw_length; $i++) . l0 z0 I1 m0 U4 x, Y; I
05.    {
5 I) |3 w: x- w* h+ J# K06.        $randpwd .= chr(mt_rand(33, 126));
( G+ ~9 B% J7 s& O- K% T5 {07.    }4 c! u# ]* w9 s6 H$ E4 `
08.    return $randpwd;
1 f' P- k* O. `; _) \0 a09.}9 s+ o/ T$ K7 {
10.   {9 k& k& T  M  i
11.// 调用该函数,传递长度参数$pw_length = 6
5 Q1 j( N* X! H# ?12.echo create_password(6);& H& Q9 E" r( S8 @; v) t

, y. {  ~4 q8 B" @" Z% p7 e; F: F) C; T0 [$ b# N' P3 W
方法二:1、预置一个的字符串 $chars ,包括 a – z,A – Z,0 – 9,以及一些特殊字符7 |# h! s+ v5 T- {+ r3 o
2、在 $chars 字符串中随机取一个字符
8 R$ s) p5 D; z+ S0 w3、重复第二步 n 次,可得长度为 n 的密码0 ^8 n. c* {, {3 Z  p) ?
view source4 g8 f6 E5 b  H- L; c
print?& v* p, y$ T7 |. E* N% O

/ c/ Z! ]5 b  Z7 ~+ t1 h& Y) |01.function generate_password( $length = 8 ) {. i. l% ]4 v1 Y2 T
02.    // 密码字符集,可任意添加你需要的字符
: r; p5 y; q; J8 c9 W% ^03.    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_ []{}<>~`+=,.;:/?|';
! H( t* b: f) q& V04. # |1 j. l; H" N' n7 m  `
05.    $password = '';
  Y3 L! x0 S. h- C2 n06.    for ( $i = 0; $i < $length; $i++ ) 0 N5 G; N, ]- M5 |, O$ ?; q
07.    {
( c3 A: S/ m* X08.        // 这里提供两种字符获取方式
- h, P/ O* b( b+ B9 d# g09.        // 第一种是使用 substr 截取$chars中的任意一位字符;
0 ^( P$ H( k" ?+ u# h5 b10.        // 第二种是取字符数组 $chars 的任意元素
( p9 P. G5 ?& M; H' c# D- K11.        // $password .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);# l! }* B. g7 W4 |+ p
12.        $password .= $chars[ mt_rand(0, strlen($chars) - 1) ];
' @. S% K( }7 W+ L. J& ~13.    }) C; g3 Q- h; _0 k4 R" e& L$ F
14. " V3 w3 M3 ^/ P4 E( B% A
15.    return $password;
4 K% w2 d6 y3 F. o6 S: n+ q16.}
$ h% U. x4 v' o! G- q6 Y+ T1 w# I8 F
6 u. t$ ?2 X3 [( n' Q3 n: Q
. h' _# }( R: g: f方法三:1、预置一个的字符数组 $chars ,包括 a – z,A – Z,0 – 9,以及一些特殊字符
7 ^$ f( `( _/ E6 t* g2、通过array_rand()从数组 $chars 中随机选出 $length 个元素$ h" w* ]9 w1 b( P+ o
3、根据已获取的键名数组 $keys,从数组 $chars 取出字符拼接字符串。该方法的缺点是相同的字符不会重复取。! j! c5 l$ I* j% I+ |) O: K
view source. \2 t$ u" C8 k* z6 b
print?/ ?# e7 N3 y6 w% k" t) s# I0 |+ f7 f- X
; @/ j; T% w3 J9 c  e5 j
01.function make_password( $length = 8 )- G& k- I2 T+ T6 d0 _2 l! n5 H  s
02.{; o: f; U/ k4 t6 |- g5 m; g) \
03.    // 密码字符集,可任意添加你需要的字符& B! W) F3 q' t, s; _
04.    $chars = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', ; o  P1 Y3 J! b
05.    'i', 'j', 'k', 'l','m', 'n', 'o', 'p', 'q', 'r', 's', ( o( U) \( g! D0 C& ]+ T$ }
06.    't', 'u', 'v', 'w', 'x', 'y','z', 'A', 'B', 'C', 'D', ; z5 g+ d+ W, J
07.    'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L','M', 'N', 'O', , Z. s6 D& N# s6 Z# ~
08.    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y','Z', 9 Z8 C1 d( j7 W* v# \, i8 g
09.    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '!', 6 j/ c8 G: b  Q7 w4 p6 e& j
10.    '@','#', '$', '%', '^', '&', '*', '(', ')', '-', '_',
3 P7 x/ r: ^+ |" n' j- n/ s1 K11.    '[', ']', '{', '}', '<', '>', '~', '`', '+', '=', ',',
5 L6 e/ {: {# F5 @; N12.    '.', ';', ':', '/', '?', '|');
( B2 w4 h/ m# [9 q13. 4 y7 E& F$ Q6 C' e6 f# U
14.    // 在 $chars 中随机取 $length 个数组元素键名
/ `. H7 x2 s+ v. B8 ~$ U9 |: S15.    $keys = array_rand($chars, $length); ) a2 J, G& H; L  o% z- e8 e5 _, j
16. 4 r! d1 c: Y- @
17.    $password = '';
  E4 L( d& \# ?  D9 q5 ?, e3 X, I: @18.    for($i = 0; $i < $length; $i++)
- l* v3 K, z9 f: |; h& N19.    {
5 [' r6 N. y3 p20.        // 将 $length 个数组元素连接成字符串
2 F* A( ]6 z: \( Q: b21.        $password .= $chars[$keys[$i]];( N& \1 l, F' ]5 u! Q( R# t. j
22.    }
0 o; l' B( B* i0 d6 m$ f23. ; ?6 I/ m% o) n* q
24.    return $password;4 A5 Q, J1 K4 X8 K/ z4 |) q' O0 ^
25.}" o8 x- f7 @7 B

# U* ~  S# z, i: T/ Y# }2 i3 Y7 @0 C2 q8 e8 _3 g) o7 t
方法四:本方法是本文被蓝色理想转载后,一名网友提供的一个新方法,算法简单,代码简短,只是因为md5()函数的返回值的缘故,生成的密码只包括字母和数字,不过也算是一个不错的方法。算法思想:  H- o5 M+ {' K  G7 P, Z
1、time() 获取当前的 Unix 时间戳) B' _5 [$ j0 h/ I2 L
2、将第一步获取的时间戳进行 md5() 加密6 d& e) e1 f$ }: \* I
3、将第二步加密的结果,截取 n 位即得想要的密码
! k; D: v+ O0 l! H+ o4 u7 T  `view source
+ f6 k1 F- b# t: \* Kprint?
9 T# ^5 c) I. P  p: t6 x
8 }: X, @1 H. q& q  F2 A! j' D1.function get_password( $length = 8 ) # m" F) D: w& ^4 `" L; q3 o3 b
2.{
9 x) j7 F* ^6 E: w& b  R# ~3.    $str = substr(md5(time()), 0, 6);
. h6 l9 M5 Q; K% ^4.    return $str;$ N# e- Y# g+ O% k
5.}
1 y, z- D3 Q5 _' g
/ S1 d8 {9 N" d3 o4 A/ s
" V# b' i' y, J- [时间效率对比我们使用以下PHP代码,计算上面的 4 个随机密码生成函数生成 6 位密码的运行时间,进而对他们的时间效率进行一个简单的对比。1 i' E% o. K9 g( t( p
view source
; S% D0 x/ C" g3 A# L3 Mprint?5 R6 I4 B2 L' @7 k' D! |

5 v3 @& Z1 D1 g& U01.<?php
8 x8 L$ I: q) E1 P02.function getmicrotime()
; T' r9 z1 S- |0 M% m03.{' _' ]& b- Z" x. i, Z5 T
04.    list($usec, $sec) = explode(" ",microtime());
, c) i( ~# n, R# c* I$ F5 ?9 N9 i05.    return ((float)$usec + (float)$sec);
+ o  _8 c( U4 ^% C2 ?1 T4 f06.}
0 P4 {3 l$ B: ?+ r07. ' I( |1 q: W! z  T4 W
08.// 记录开始时间3 l6 |1 w4 R, v; {
09.$time_start = getmicrotime();2 ^& h+ V8 d3 D, Y
10. * `, ?4 N& @/ J' ^! b9 @; q
11.// 这里放要执行的PHP代码,如:" Y; a) b0 L$ `9 W- p) n3 H
12.// echo create_password(6);
3 c% j& b$ @: A% {+ s6 `. P( T4 y, W13. & l9 v/ l. k9 L$ y$ ~+ u. V" \+ \
14.// 记录结束时间
8 j+ \3 ^/ |, L# H' b% @8 F15.$time_end = getmicrotime();
- c( w8 n! }( N) z$ F' U& L16.$time = $time_end - $time_start;
+ X$ k/ h8 [% P* d8 ~' ?1 \17.
# N5 I6 ~1 |" a  Q: t: D8 ~, _9 [18. // 输出运行总时间 9 I  w' ~/ h+ h3 h' |
19.echo "执行时间 $time seconds";: C4 V  r. M7 g( r# t6 ^4 t
20.?>
5 c3 E! z  M  X9 A
% u' @% M: t& [2 _: j
  K: k0 N3 f7 i最终得出的结果是:
9 P& ?) @! h( Y$ E' M% q% J  L方法一:9.8943710327148E-5 秒- N+ B9 n+ U( V: Z" ?& U9 T
方法二:9.6797943115234E-5 秒
' i# k) X$ E, @+ s方法三:0.00017499923706055 秒3 [9 u  G7 E- Z# g6 h" s( i1 H
方法四:3.4093856811523E-5 秒6 Y! t1 u" N! O) ?( k8 r0 L
可以看出方法一和方法二的执行时间都差不多,方法四运行时间最短,而方法三的运行时间稍微长点。
6 j& c+ w# }4 g7 d' @
9 w7 ?+ {- u# w( R. V
9 M. f# k5 e% c% r4 h% `! S* h




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5