如何生成一个随机、唯一、包含字母和数字的字符串?

493

如何使用数字和字母生成一个随机且唯一的字符串用于验证链接?就像在网站上创建账户并通过电子邮件发送带有链接的邮件,您需要点击该链接以验证您的账户一样。

我如何使用PHP生成此类字符串?


1
你所需要的仅是字符串和均匀分布的随机数。 - Artelius
12
嗨,安德鲁,你应该选择“Scott”作为正确答案。 Scott正在使用OpenSSL的加密安全伪随机数生成器(CSPRNG),它将基于您的平台选择最安全的熵源。 - rook
3
阅读此内容的任何人,如果在2015年之后,请务必注意:https://paragonie.com/blog/2015/07/how-safely-generate-random-strings-and-integers-in-php 大多数最佳答案或多或少存在缺陷... - rugk
OpenSSL和uniqid是不安全的。使用类似于Random::alphanumericString($length)或者Random::alphanumericHumanString($length)这样的东西。 - caw
31个回答

7
这是一个简单的函数,允许您生成包含字母和数字(字母数字混合)的随机字符串。您还可以限制字符串长度。 这些随机字符串可用于各种目的,包括:推荐代码、促销代码、优惠券代码。 该函数依赖以下PHP函数: base_convert、sha1、uniqid、mt_rand
function random_code($length)
{
  return substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, $length);
}

echo random_code(6);

/*sample output
* a7d9e8
* 3klo93
*/

6
尝试生成随机密码时,您需要执行以下步骤:
  • 首先生成一个具有加密安全性的随机字节集

  • 第二步是将这些随机字节转换成可打印字符串

现在,在PHP中有多种方法可以生成随机字节,例如:
$length = 32;

//PHP 7+
$bytes= random_bytes($length);

//PHP < 7
$bytes= openssl_random_pseudo_bytes($length);

您希望将这些随机字节转换为可打印字符串:

您可以使用bin2hex函数:

$string = bin2hex($bytes);

或者 base64_encode

$string = base64_encode($bytes);

请注意,如果使用base64编码,您无法控制字符串的长度。 您可以使用bin2hex来控制长度,使用 32字节 将变为 64个字符的字符串 。 但是,它只能在偶数长度下正常工作。

因此,您只需执行以下操作:

$length = 32;

if(PHP_VERSION>=7){
    $bytes= random_bytes($length);
}else{
    $bytes= openssl_random_pseudo_bytes($length);
} 

$string = bin2hex($bytes);

4
以下是我使用的内容:
md5(time() . rand());    
// Creates something like 0c947c3b1047334f5bb8a3b7adc1d97b

最好的选择,如果某人只是寻找用于数据库种子数据的单行代码。 - Sahil Jain

4

这是一个简单的“一行”字符串哈希生成器,例如77zd43-7bc495-64cg9a-535548(1字节=2个字符)。

  $hash = implode('-', [
       bin2hex(random_bytes(3)),
       bin2hex(random_bytes(3)),
       bin2hex(random_bytes(3)),
       bin2hex(random_bytes(3)),
    ]);

3

这个人噎到了一杯水...

$random= substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*.-_"), 0, 10);

简单易懂。 这个随机字符串重复的可能性是 0.000000000000000000000000000001^70。


这可以防止重复获取一个字符。生成一个由10个a组成的字符串应该是可能的。因此,该字符串也应该被重复10次的长度。 - halloei
1
10秒钟内有18个光线更可能击中你。 - Andres Rave

2

这是一款由我开发的终极唯一ID生成器,适用于您的需求。

<?php
$d=date ("d");
$m=date ("m");
$y=date ("Y");
$t=time();
$dmt=$d+$m+$y+$t;    
$ran= rand(0,10000000);
$dmtran= $dmt+$ran;
$un=  uniqid();
$dmtun = $dmt.$un;
$mdun = md5($dmtran.$un);
$sort=substr($mdun, 16); // if you want sort length code.

echo $mdun;
?>

你可以随意使用任何“var”来代替你的id。但是$mdun更好,你可以将md5替换为sha1以获得更好的代码,但那会很长,可能你不需要。

谢谢。


7
在这种情况下,随机性是由随机编写的代码来保证的,对吗? - Daniel Kucal
3
这段话的意思是,这段代码不是标准的、晦涩难懂的代码,因此很难预测它的行为。但实际上,它使用了不安全的部分来生成随机数,所以结果在技术上既不是随机的也不安全。请注意,这是一种“随意”的表达方式。 - Philipp

2
function random_string($length = 8) {
    $alphabets = range('A','Z');
    $numbers = range('0','9');
    $additional_characters = array('_','=');
    $final_array = array_merge($alphabets,$numbers,$additional_characters);
       while($length--) {
      $key = array_rand($final_array);

      $password .= $final_array[$key];
                        }
  if (preg_match('/[A-Za-z0-9]/', $password))
    {
     return $password;
    }else{
    return  random_string();
    }

 }

2

在处理验证链接时,我喜欢使用哈希键。建议使用微秒时间戳并使用MD5进行哈希,因为它基于微秒时间戳进行哈希,所以不应该存在相同的键。

  1. $key = md5(rand());
  2. $key = md5(microtime());

2
如果您想在PHP中生成唯一的字符串,请尝试以下操作。
md5(uniqid().mt_rand());

在这里,

uniqid() - 它将生成唯一的字符串。此函数返回基于时间戳的唯一标识符作为字符串。

mt_rand() - 生成随机数。

md5() - 它将生成哈希字符串。


2
<?php
function generateRandomString($length = 11) {
    $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $length; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;

}

?>

上述函数会生成一个长度为11个字符的随机字符串。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接