Home » Code » 如何用PHP创建一个随机字符串

如何用PHP创建一个随机字符串

某些场景下,需要创建一个随机的字符串,比如上传下载文件时重新命名之(当然这种情况下也可以对文件取md5或者sha1值)。PHP是自带了相关函数的,比如uniqid(),可以生成一个带前缀的基于当前时间微秒的唯一ID。

echo uniqid();//586a51d18afa8
echo uniqid('prefix_');//prefix_586a51d18afb3
echo uniqid('prefix_', true);//prefix_586a51d18afb91.73536434

uniqid()函数创建的字符串正如它的名字一样,可能更强调唯一性,并非随机性,它是伪随机(Pseudo-Random)的。除了uniqid(),还可以使用openssl相关的openssl_random_pseudo_bytes()函数来生成,这个函数也是伪随机的,而且生成的是二进制的位字符串,一般转换为16进制来使用。

$r = openssl_random_pseudo_bytes(8);
echo strlen($r);//8
$r = bin2hex($r);
echo strlen($r);//16
echo $r;//2f5f6b7275a784a2

在PHP 7中,官方提供了random_bytes()来创建更安全的伪随机字符串:

$r = random_bytes(10);
echo strlen($r);//10
$r2 = bin2hex($r);
echo strlen($r2);//20
echo $r2;//ad5fafd944961e2af548

同时有一个random_int()来创建一定范围内的随机整数。

在PHP 5项目中,如果想使用random_bytes(),可以使用random_compat这个库。

在其他一库框架中,是怎么创建随机字符串的呢?在国外最受欢迎的框架Laraval中,用的就是random_bytes()(PHP 7)和openssl_random_pseudo_bytes()(PHP 5),只不过它是进行base64_encode()而不是bin2hex()。

public static function random($length = 16)
{
    $string = '';

    while (($len = strlen($string)) < $length) {
        $size = $length - $len;

        $bytes = static::randomBytes($size);

        $string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
    }

    return $string;
}
public static function randomBytes($length = 16)
{
    if (PHP_MAJOR_VERSION >= 7 || defined('RANDOM_COMPAT_READ_BUFFER')) {
        $bytes = random_bytes($length);
    } elseif (function_exists('openssl_random_pseudo_bytes')) {
        $bytes = openssl_random_pseudo_bytes($length, $strong);

        if ($bytes === false || $strong === false) {
            throw new RuntimeException('Unable to generate random string.');
        }
    } else {
        throw new RuntimeException('OpenSSL extension or paragonie/random_compat is required for PHP 5 users.');
    }

    return $bytes;
}

上边方案创建的随机字符串,可能不够唯一,在某些场景,比如订单号,比如大数据分布式的ID,对唯一性要求非常高。这时候可能听说过所谓的UUID。UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。PHP没有提供原生函数来生成,需要的话可以使用这个库ramsey/uuid这个库来生成。当然,除了UUID,也有其他公司的一些方案,比如twitter的SnowFlake,但用PHP不好实现,有兴趣的可以自行了解。

参考链接:
https://paragonie.com/blog/2015/07/how-safely-generate-random-strings-and-integers-in-php
http://mp.weixin.qq.com/s?__biz=MzA5ODM0NjA3NA==&mid=2651209088&idx=1&sn=640af6452e8644e65c5c5985eb405358

One comment

  1. 我就一个感觉,好高深= =

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Time limit is exhausted. Please reload CAPTCHA.