如何生成随机的,唯一的字母数字字符串?

2022-08-30 05:51:30

如何使用数字和字母生成一个随机的、唯一的字符串,以便在验证链接中使用?就像您在网站上创建帐户一样,它会向您发送一封带有链接的电子邮件,您必须单击该链接才能验证您的帐户

我如何使用PHP生成其中之一?


答案 1

PHP 7 标准库提供了生成加密安全的伪随机字节的函数。random_bytes($length)

例:

$bytes = random_bytes(20);
var_dump(bin2hex($bytes));

上面的示例将输出类似于以下内容的内容:

string(40) "5fe69c95ed70a9869d9f9af7d8400a6673bb9ce9"

更多信息: http://php.net/manual/en/function.random-bytes.php

PHP 5 (已过时)

我只是在研究如何解决同样的问题,但我也希望我的函数创建一个可用于密码检索的令牌。这意味着我需要限制令牌被猜测的能力。因为uniqid是基于时间的,并且根据 php.net“返回值与microtime()几乎没有区别”,不符合标准。PHP 建议改为使用来生成加密安全的令牌。uniqidopenssl_random_pseudo_bytes()

一个快速,简短且切中要害的答案是:

bin2hex(openssl_random_pseudo_bytes($bytes))

这将生成一个长度 = $bytes * 2 的字母数字字符的随机字符串。不幸的是,这只有一个字母表,但它有效。[a-f][0-9]


以下是我能做出的最强函数,它满足了标准(这是Erik答案的实现版本)。
function crypto_rand_secure($min, $max)
{
    $range = $max - $min;
    if ($range < 1) return $min; // not so random...
    $log = ceil(log($range, 2));
    $bytes = (int) ($log / 8) + 1; // length in bytes
    $bits = (int) $log + 1; // length in bits
    $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
    do {
        $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
        $rnd = $rnd & $filter; // discard irrelevant bits
    } while ($rnd > $range);
    return $min + $rnd;
}

function getToken($length)
{
    $token = "";
    $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
    $codeAlphabet.= "0123456789";
    $max = strlen($codeAlphabet); // edited

    for ($i=0; $i < $length; $i++) {
        $token .= $codeAlphabet[crypto_rand_secure(0, $max-1)];
    }

    return $token;
}

crypto_rand_secure($min, $max)用作 或 的替换。它使用openssl_random_pseudo_bytes来帮助在$min和$max之间创建随机数。rand()mt_rand

getToken($length)创建要在令牌中使用的字母表,然后创建长度字符串。$length

资料来源:http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322


答案 2

安全声明:此解决方案不应在随机性质量可能影响应用程序安全性的情况下使用。特别是,rand()uniqid() 不是加密安全的随机数生成器。请参阅斯科特的答案,了解安全的替代方案。

如果您不需要它随着时间的推移绝对唯一:

md5(uniqid(rand(), true))

否则(假设您已经为用户确定了唯一登录名):

md5(uniqid($your_user_login, true))

推荐