首先,让我说几乎没有事件是真正随机的。 如果我们知道所涉及的每个因素(例如空气摩擦,重力和初始力)的影响,那么即使从理论上讲,经典的抛硬币的结果也可以预测。

同样的情况适用于随机数和字母数字字符串的生成。 我们可以期望的最好的办法是生成似乎不遵循某种模式并且实际上无法被攻击者预测的数字和字符串。

在本教程中,我们将介绍在PHP中生成随机数和字母数字字符串的不同技术。 其中一些将是加密安全的,而另一些则仅用于临时使用,例如分配伪随机文件名或创建URL并建议用户名。

在PHP中生成随机数

在PHP中,可以使用三种不同的函数来生成随机数。 它们都将接受随机数的最小和最大值,并为您输出一个随机数。 这些是rand($min, $max)mt_rand($min, $max)random_int($min, $max)

使用rand() ,您可以生成的整数的最小值和最大值在0getrandmax()返回的值之间。 在PHP 7.1.0之前,此功能比mt_rand()慢大约四倍。 但是,从PHP 7.1.0开始,它已成为mt_rand()的别名。 但是,与mt_rand()不同,您可以将$max的值设置为小于$min而不引起错误。

使用mt_rand() ,可以生成的整数的最小值和最大值介于0mt_getrandmax()返回的值之间。 它依靠Mersenne Twister的实现来生成随机数。 但是请注意,在PHP 7.1.0之前,此函数实现了错误版本的算法来生成数字。 但是,它已在较新版本中修复。

通过消除模块偏差错误,该功能在PHP 7.2.0中变得更好。 这意味着对于某些特定的种子,您的随机数序列现在将比旧版本更好。 但是,某些专用代码实际上可能依赖于这种偏见。 如果是这样,则可以通过调用mt_srand()函数为随机数生成器作为种子并将MT_RAND_PHP用作第二个参数的值来使用较早的种子算法。

mt_rand()函数的周期为2 19937 -1,这基本上意味着,在最佳情况下,在序列开始重复之前,您将获得2 19937 -1个随机数。 您应注意,序列的重复与特定编号的重复不同。 换句话说,您可能会两次获得相同的随机数,但这并不意味着序列本身已经开始重复。 以下序列是一个示例:

187 3276 1267 15 1267 34598 3467 125 17

在上面的序列中,输出两次有1267,但这并不意味着整个序列在此之后开始重复。 不可能很快以随机顺序重复相同的数字,但是有可能!

加密安全随机整数

如果您希望使用密码安全的伪随机数,那么PHP中的random_int()函数是您最好的选择。 它将在提供的$min$max值之间生成随机数,默认为PHP_INT_MINPHP_INT_MAX 。 不幸的是,此功能仅从PHP 7.0起可用。 对于之前的版本,您可以在GitHub上使用此polyfill 。

随机浮动

除了生成随机整数,您可能还希望生成浮点数。 只需将随机数除以mt_getrandmax()返回的值,就可以轻松完成此操作。 下面的示例将说明如何生成介于0和1之间或任何其他最小与最大限制之间的随机浮点数。

<?php// Output: 0.69458310943776
echo mt_rand(0, mt_getrandmax())/mt_getrandmax();function mt_random_float($min, $max) {$float_part = mt_rand(0, mt_getrandmax())/mt_getrandmax();$integer_part = mt_rand($min, $max - 1);return $integer_part + $float_part;
}// Output: 10.199064863938
echo mt_random_float(10, 11);// Output: 35.540808309121
echo mt_random_float(15, 50);?>

在给定限制之间生成随机浮点数时,我们确保随机整数不会超过$max - 1 。 这样,我们可以确保添加浮点数不会超过最大限制。

播种随机数生成器

需要一点解释的一个概念是种子。 简而言之,这些只是可用于在生成任何随机数之前初始化rand()mt_rand()函数的数字。 播种rand()的函数称为srand($seed) ,播种mt_rand()mt_srand($seed, $mode)称为mt_srand($seed, $mode)

重要的是要记住,在调用rand()mt_rand()之前每次提供初始种子值不一定会产生更好的随机数。 实际上,每次使用相同的种子也将为您提供相同的随机数!

<?phpmt_srand(10);
// Output: 1656398468
echo mt_rand();mt_srand(10);
// Output: 1656398468
echo mt_rand();mt_srand(10);
// Output: 1656398468
echo mt_rand();?>

在要生成随机但可重现的序列的情况下,播种随机数很有用。 下面的代码片段在运行两次时会生成相同的随机数序列。

<?phpmt_srand(10);$count = 0;while($count < 10) {echo mt_rand(0, 100)." ";$count++;
}// Output on First Run:
// 68 58 68 13 3 48 30 37 96 82// Output on Second Run:
// 68 58 68 13 3 48 30 37 96 82

通过这种方式生成可重现的随机序列可以帮助调试使用随机数据测试的程序-如果您跟踪种子,则可以重现相同的输入以找出问题所在。

在PHP中生成随机字母数字字符串

生成随机字母数字字符串的方法有很多,具体使用哪种取决于您的需求。

生成随机的字符串

如果要从一组固定的字符生成随机的字母数字字符串,可以使用str_shuffle($string)函数。 此函数将为您提供随机混洗的字符串。 从PHP 7.1开始,用于确定输出字符串中字符的随机顺序的算法已更改为Mersenne Twister。

请记住,以这种方式生成的随机字符串不是加密安全的。 但是,对于生成随机文件名或URL之类的常用字符串而言,该字符串仍然非常难以预测。 这里有一些例子:

<?php$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyz';
// Output: 54esmdr0qf
echo substr(str_shuffle($permitted_chars), 0, 10);$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
// Output: video-g6swmAP8X5VG4jCi.mp4
echo 'video-'.substr(str_shuffle($permitted_chars), 0, 16).'.mp4';?>

在两种情况下,您的输出很可能会有所不同。 在第一种情况下,我们只是对允许的字符串进行了混洗,然后采用了它的前10个字符。 在第二种情况下,我们在生成的字符串的开头添加了“视频”,并在其结尾添加了“ .mp4”。

这种生成随机字母数字字符串的方法非常简单,但是存在两个问题。 例如,您永远不会在随机字符串中两次获得相同的字符。 同样,随机输出字符串的长度只能与输入字符串一样长。

生成随机字符串

如果我上面列出的问题破坏了交易,那么您可能希望查看其他一些实现。 以下代码将解决这两个问题。

<?php$permitted_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';function generate_string($input, $strength = 16) {$input_length = strlen($input);$random_string = '';for($i = 0; $i < $strength; $i++) {$random_character = $input[mt_rand(0, $input_length - 1)];$random_string .= $random_character;}return $random_string;
}// Output: iNCHNGzByPjhApvn7XBD
echo generate_string($permitted_chars, 20);// Output: 70Fmr9mOlGID7OhtTbyj
echo generate_string($permitted_chars, 20);// Output: Jp8iVNhZXhUdSlPi1sMNF7hOfmEWYl2UIMO9YqA4faJmS52iXdtlA3YyCfSlAbLYzjr0mzCWWQ7M8AgqDn2aumHoamsUtjZNhBfU
echo generate_string($permitted_chars, 100);?>

您可以对其进行修改,以在生成的随机字符串中添加特定的后缀和前缀。 使用PHP 7的人可以使用加密安全的函数random_int()而不是mt_rand()来进一步改善字符串生成。

生成随机的十六进制字符串

如果要在PHP中生成随机的十六进制字符串,还可以使用md5($string, $raw_output)sha1($string, $raw_output)函数。 它们都将生成给定输入字符串的哈希。

只要输入是唯一的,您就将不断获得唯一的哈希。 这可以通过使用类似time()的函数的输出作为输入来实现。 默认情况下, md5()将返回32个字符的十六进制字符串,而sha1()将返回40个字符的十六进制字符串。 可以使用substr()函数将它们修剪为特定的长度。

这是这些函数返回的输出的示例:

<?php// Output: 36e5e490f14b031e
echo substr(md5(time()), 0, 16);// Output: aa88ef597c77a5b3
echo substr(sha1(time()), 0, 16);// Output: 447c13ce896b820f353bec47248675b3
echo md5(time());// Output: 6c2cef9fe21832a232da7386e4775654b77c7797
echo sha1(time());?>

如您所见,在PHP中生成长达40个字符的随机且唯一的十六进制字符串非常容易。

生成加密安全的随机字符串

到目前为止,我们讨论的生成随机字母数字字符串的三个函数在密码上都不安全。 幸运的是,PHP还具有一个称为random_bytes($length)的函数,用于生成加密安全的伪随机字节。 $length参数确定输出字符串应多长。

一旦有了随机字节的输出,就可以使用bin2hex()函数将其转换为十六进制值。 这将使字符串的长度加倍。

<?php// Output: b7b33efa07915b60ad55
echo bin2hex(random_bytes(10));// Output: a2e6cb1f25616324c8a11a2cceb0b47c590949ea
echo bin2hex(random_bytes(20));// Output: 25af3b86e11884ef5e8ef70a0ad06cba81b89ed6af3781a0
echo bin2hex(random_bytes(24));?>

可以用来生成加密安全的随机字节的另一个函数是openssl_random_pseudo_bytes($length, &$crypto_strong) 。 第二个参数的值可用于确定是否将使用密码安全算法生成输出字符串。

最后的想法

在本教程中,我们研究了PHP中随机数和字母数字字符串的生成。 生成随机数在各种情况下都非常有用,例如在游戏中,您必须生成敌方玩家或随机为用户提供有关字母的线索,以便他们可以组成一个完整的单词。

就像随机数一样,在许多情况下,随机字母数字字符串的生成也非常有用。 借助str_shuffle() ,您可以选择随机字符串中出现的字符集。 使用sha1()md5() ,您可以轻松生成随机的十六进制序列,而使用random_bytes()可以生成加密安全的字符串。 这将使您生成难以猜测的有意义但随机的文件名和用户名。

希望您喜欢本教程。 如果您有任何疑问,请随时在评论中提问。

翻译自: https://code.tutsplus.com/tutorials/generate-random-alphanumeric-strings-in-php--cms-32132

在PHP中生成随机的字母数字字符串相关推荐

  1. 如何生成随机的字母数字字符串?

    我一直在寻找一种简单的 Java算法来生成伪随机的字母数字字符串. 在我的情况下,它将用作唯一的会话/密钥标识符,在"超过500K+世代中"可能"是唯一的(我的需求实际上 ...

  2. python随机生成英文字母_在Python中生成随机字母

    有没有一种方法可以在Python中生成随机字母(如random.randint,但用于字母)? random.randint的范围功能会很好,但是拥有仅输出随机字母的生成器总比没有好. 简单: > ...

  3. 定义一个方法,使用随机的字母+数字生成一个6位数的密码

    @Testpublic void test10() {//调用PassWord方法打印输出System.out.println(PassWord());}//定义一个方法,使用随机的字母+数字生成一个 ...

  4. 随机生成6位字母+数字混合密码

    随机生成6位字母+数字混合密码 //定义密码位数private final static int PWD_LENGTH = 6; public static String getPwdRandom() ...

  5. 在JavaScript中生成随机字符串/字符

    我想要一个由从[a-zA-Z0-9]随机挑选的字符组成的5个字符串. 用JavaScript做到这一点的最佳方法是什么? #1楼 我认为这将为您工作: function makeid(length) ...

  6. 如何在C中生成随机int?

    是否有在C中生成随机int数的函数? 或者我必须使用第三方库吗? #1楼 让我们来看看. 首先,我们使用srand()函数为随机化器播种. 基本上,计算机可以根据提供给srand()的数字生成随机数. ...

  7. python 组合数字和字符_python无限生成不重复(字母,数字,字符)组合的方法

    python无限生成不重复(字母,数字,字符)组合的方法 使用python自带的itertools模块 调用其product函数 传入我们想组合生成的字符数据 便会源源不断的生成组合 而且不会重复 r ...

  8. 从字母数字字符串中提取数字

    http://office.microsoft.com/zh-cn/excel-help/HA001154901.aspx 本文的作者是 Ashish Mathur,是一位 Microsoft MVP ...

  9. js生成随机不重复数字的几种方法

    三种方式实现生成随机不重复数字: <!DOCTYPE html> <html> <head><title>生成随机不重复数</title> ...

最新文章

  1. 又见yx — 说说IT公司的团队头儿
  2. 标准化工作导则2020_最新版 GB/T 1.12020 标准化工作导则 第 1 部分:标准化文件的结构和起草规则标准解读...
  3. SAP CRM WebClient UI Text Type 显示的过滤逻辑
  4. C#中容器控件GroupBox、Panel、TabControl
  5. 利用pdf.js开发嵌入pdf显示,以及利用jquery-ui左右分栏显示
  6. mysql日期格式化季度_mysql按年度、季度、月度、周、日统计查询的sql语句
  7. 请教:如何进行存储过程的调试
  8. 《C++编程——数据结构与程序设计方法》程序范例:影碟店(源代码)
  9. 卸载linux订阅包
  10. c语言二叉树链式存储,C语言 二叉树的链式存储实例
  11. Threat Risk Modeling Learning
  12. 人工智能AI-模型训练思路
  13. 算法导论第三版习题及答案
  14. mysql车库管理系统_小区停车管理系统(JSP+JAVA+MySQL)
  15. VB实现List集合
  16. 微信App iOS客户端不同阶段的发展策略
  17. 陶瓷纤维毯行业调研报告 - 市场现状分析与发展前景预测
  18. hypixel服务器显示无法登录,我的世界hypixel服务器盗版可以登录?
  19. 微信扫码充值 php,微信扫码支付,php版
  20. Wi-Fi:802.11 物理层和发射机测量概述

热门文章

  1. 【Python】通过 requests 获取文件字节流
  2. js字符串数组转数字数组
  3. 爬虫入门,快速抓取数据
  4. 海藻酸钠-菁染料CY5|alginate-Cyanine5|CY5-peg-海藻酸钠
  5. 三角形面积的计算公式?
  6. H7-TOOL发布固件V2.21, 增加RTT快捷面板功能,脱机烧录增加英飞凌,Qorvo以及NXP,普冉,华大,灵动微等新系列(2023-03-26)
  7. Selenium爬取打卡记录并记录到表格
  8. python基于opencv工具掌纹主线提取
  9. docker镜像创建及使用
  10. 【MCS-51】时钟电路和复位