Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
77 views
in Technique[技术] by (71.8m points)

What is the best way to generate a random key within PHP?

I'm looking to create a reusable function that will generate a random key with printable ACSII characters of chosen length (anywhere from 2 to 1000+). I'm thinking printable ASCII characters would be 33-126. They key does not need to be completely unique, just unique if generated at the exact same millisecond (so uniqid() won't work).

I'm thinking a combination of chr() and mt_rand() might work.

Is this the way to go, or is something else the best method?

Edit: uniqid() will also not work because it doesn't have a length parameter, it's just whatever PHP gives you.

My Idea: This is what I came up with:

function GenerateKey($length = 16) {
    $key = '';

    for($i = 0; $i < $length; $i ++) {
        $key .= chr(mt_rand(33, 126));
    }

    return $key;
}

Are there any problems with this?

Another Edit: Most of the other questions deal with password generation. I want a wider variety of characters and I don't care about 1 vs l. I want the maximum number of possible keys to be possible.

Note: the generated key does not necessarily have to be cryptographically secure.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Update (12/2015): For PHP 7.0, you should use random_int() instead of mt_rand as it provides "cryptographically secure values"

Personally, I like to use sha1(microtime(true).mt_rand(10000,90000)) but you are looking for more of a customizable approach, so try this function (which is a modification to your request of this answer):

function rand_char($length) {
  $random = '';
  for ($i = 0; $i < $length; $i++) {
    $random .= chr(mt_rand(33, 126));
  }
  return $random;
}

Still, this will probably be significantly slower than uniqid(), md5(), or sha1().

Edit: Looks like you got to it first, sorry. :D

Edit 2: I decided to do a nice little test on my Debian machine with PHP 5 and eAccelerator (excuse the long code):

function rand_char($length) {
  $random = '';
  for ($i = 0; $i < $length; $i++) {
    $random .= chr(mt_rand(33, 126));
  }
  return $random;
}

function rand_sha1($length) {
  $max = ceil($length / 40);
  $random = '';
  for ($i = 0; $i < $max; $i ++) {
    $random .= sha1(microtime(true).mt_rand(10000,90000));
  }
  return substr($random, 0, $length);
}

function rand_md5($length) {
  $max = ceil($length / 32);
  $random = '';
  for ($i = 0; $i < $max; $i ++) {
    $random .= md5(microtime(true).mt_rand(10000,90000));
  }
  return substr($random, 0, $length);
}

$a = microtime(true);
for ($x = 0; $x < 1000; $x++)
  $temp = rand_char(1000);

echo "Rand:".(microtime(true) - $a)."
";

$a = microtime(true);
for ($x = 0; $x < 1000; $x++)
  $temp = rand_sha1(1000);

echo "SHA-1:".(microtime(true) - $a)."
";

$a = microtime(true);
for ($x = 0; $x < 1000; $x++)
  $temp = rand_md5(1000);

echo "MD5:".(microtime(true) - $a)."
";

Results:

Rand:   2.09621596336
SHA-1:  0.611464977264
MD5:    0.618473052979

So my suggestion, if you want speed (but not full charset), is to stick to MD5, SHA-1, or Uniqid (which I didn't test.. yet)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...