在编写 PHP 程序时,我们经常会使用随机函数来生成随机数,例如生成验证码、加密密码等。但是,有些人可能会遇到一个问题:即使页面没有刷新,但随机数也会变化。
这是因为 PHP 的随机函数使用的是伪随机数生成器(Pseudo Random Number Generator,PRNG),PRNG 是通过一个算法生成随机数序列的,它会根据一个称为“种子”的初始值来计算出随机数序列。在每次生成随机数时,PRNG 都会更新种子的值,以确保后续的随机数是不同的。
如果在生成随机数之前不设置种子,PRNG 会默认使用系统当前的时间为种子。这意味着,如果在同一秒钟内多次调用随机函数,则 PRNG 的种子将不会更新,因此生成的随机数序列也是相同的。
为了解决这个问题,我们可以手动为 PRNG 指定一个种子值,以确保每次生成的随机数序列都是不同的。
下面是使用 PHP mt_rand() 函数生成随机数的示例:
``` php
$seed = time(); // 设置种子值为当前时间戳
mt_srand($seed); // 初始化随机数生成器
$rand_num = mt_rand(1000, 9999); // 生成4位随机数
echo "验证码是:".$rand_num;
```
在这个示例中,我们首先使用 PHP 的 time() 函数来获取当前的时间戳,并将其作为种子值传递给 mt_srand() 函数来初始化 PRNG。然后,我们使用 mt_rand() 函数来生成一个四位数的随机数,并将其输出到屏幕上。
使用这种方法生成的随机数序列是相对安全的,因为它们不容易被预测。但是,它们仍然可能受到一些攻击,例如暴力破解和穷举攻击。
为了进一步提高安全性,我们可以采用加盐的方式来生成随机数。这意味着我们将一个伪随机字符串(称为“盐”)与随机数进行连接,并使用哈希函数来加密它们,以产生一个更加安全的随机数。
下面是一个示例,其中我们将使用 PHP 的 sha1() 函数来加密随机数和盐:
``` php
$seed = time(); // 设置种子值为当前时间戳
mt_srand($seed); // 初始化随机数生成器
$salt = "sdfsd9827fghgh+s84ds"; // 设置盐
$rand_num = mt_rand(1000, 9999); // 生成4位随机数
$secure_num = sha1($rand_num.$salt); // 加盐加密随机数
echo "验证码是:".$secure_num;
```
在这个示例中,我们使用了与之前相同的种子值和 mt_srand() 函数来初始化 PRNG。然后,我们定义了一个字符串作为“盐”,并将其与随机数连接在一起。最后,我们使用 sha1() 函数对连接后的字符串进行加密,并将其输出到屏幕上。
使用加盐的方式生成的随机数更加难以被攻击者预测,因为它们需要知道盐字符串的值才能够成功地暴力破解或穷举攻击它们。但是,这并不意味着它们是完全安全的。黑客仍然可以使用其他手段来推导出随机数的值,例如使用 XSS 攻击窃取盐字符串。
因此,对于需要高度安全性的程序,我们建议使用真随机数生成器(True Random Number Generator,TRNG)。TRNG 是通过硬件设备生成真正的随机数的,例如通过测量环境中的噪声、电磁辐射等。使用 TRNG 生成的随机数序列是完全随机的,因此更加安全。但是,由于它们需要昂贵的硬件设备来生成,因此并不是所有程序都能够使用 TRNG。 如果你喜欢我们三七知识分享网站的文章, 欢迎您分享或收藏知识分享网站文章 欢迎您到我们的网站逛逛喔!https://www.ynyuzhu.com/
发表评论 取消回复