如何可能生成一个随机的,唯一的字符串使用数字和字母用于验证链接?就像你在一个网站上创建了一个账户,它会给你发一封带有链接的电子邮件,你必须点击那个链接才能验证你的账户

如何使用PHP生成其中一个?


当前回答

当尝试生成一个随机密码时,您正在尝试:

首先生成一组加密安全的随机字节 第二是将这些随机字节转换为可打印的字符串

现在,在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字符的字符串。 但它只会在EVEN字符串中这样工作。

所以基本上你可以这样做:

$length = 32;

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

$string = bin2hex($bytes);

其他回答

我在这里提供了一些很好的研究数据,基于斯科特的答案提供的功能。因此,我为这个为期5天的自动化测试设置了一个数字海洋液滴,并将生成的唯一字符串存储在MySQL数据库中。

在这个测试期间,我使用了5个不同的长度(5、10、15、20、50),每个长度插入+/- 50万条记录。在我的测试中,在50万个重复中,只有长度5产生了+/-3K个重复,其余长度没有产生任何重复。所以我们可以说,如果我们使用Scott函数的长度为15或以上,那么我们就可以生成高度可靠的唯一字符串。以下是我的研究数据:

更新

我使用这些函数创建了一个简单的Heroku应用程序,它将令牌作为JSON响应返回。该应用程序可以在https://uniquestrings.herokuapp.com/api/token?length=15上访问

这个函数将使用数字和字母生成一个随机键:

function random_string($length) {
    $key = '';
    $keys = array_merge(range(0, 9), range('a', 'z'));

    for ($i = 0; $i < $length; $i++) {
        $key .= $keys[array_rand($keys)];
    }

    return $key;
}

echo random_string(50);

示例输出:

zsd16xzv3jsytnp87tk7ygv73k8zmr0ekh6ly7mxaeyeh46oe8

我用了这样一句话:

base64_encode(openssl_random_pseudo_bytes(3 * ($length >> 2)));

其中length是所需字符串的长度(能被4整除,否则它会四舍五入到最接近的能被4整除的数字)

斯科特,是的,你写得很好,解决得很好!谢谢。

我还需要为我的每个用户生成唯一的API令牌。以下是我的方法,我使用用户信息(Userid和Username):

public function generateUniqueToken($userid, $username){

        $rand = mt_rand(100,999);
    $md5 = md5($userid.'!(&^ 532567_465 ///'.$username);

    $md53 = substr($md5,0,3);
    $md5_remaining = substr($md5,3);

    $md5 = $md53. $rand. $userid. $md5_remaining;

    return $md5;
}

请看看,如果我能做什么改进,请告诉我。谢谢

这是一个有趣的问题

public function randomStr($length = 16) {
    $string = '';
        
    while (($len = strlen($string)) < $length) {
        $size = $length - $len;
            
        $bytes = random_bytes($size);
            
        $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
    }
        
        return $string;
}

从laravel偷来的