我正在尝试在PHP中创建一个随机字符串,我绝对没有输出:
<?php
function RandomString()
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < 10; $i++) {
$randstring = $characters[rand(0, strlen($characters))];
}
return $randstring;
}
RandomString();
echo $randstring;
我究竟做错了什么?
要具体回答这个问题,有两个问题:
$randstring
不在范围内。这是一个带有更正的代码片段:
function generateRandomString($length = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
使用以下调用输出随机字符串:
// Echo the random string.
// Optionally, you can give it a desired string length.
echo generateRandomString();
请注意,这会生成可预测的随机字符串。如果你想创建安全令牌,see this answer。
函数范围中的$randstring
与您调用它的范围不同。您必须将返回值分配给变量。
$randstring = RandomString();
echo $randstring;
或者只是直接回显返回值:
echo RandomString();
此外,在你的功能中你有一点错误。在for循环中,您需要使用.=
,以便每个字符都附加到字符串。通过使用=
,您将使用每个新字符覆盖它而不是附加。
$randstring .= $characters[rand(0, strlen($characters))];
首先,定义要使用的字母表:
$alphanum = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$special = '~!@#$%^&*(){}[],./?';
$alphabet = $alphanum . $special;
然后,使用openssl_random_pseudo_bytes()
生成适当的随机数据:
$len = 12; // length of password
$random = openssl_random_pseudo_bytes($len);
最后,使用此随机数据创建密码。因为$random
中的每个字符都可以是chr(0)
,直到chr(255)
,代码使用$alphabet_length
除以其序数值后的余数,以确保只挑选字母表中的字符(注意这样做会使随机性偏差):
$alphabet_length = strlen($alphabet);
$password = '';
for ($i = 0; $i < $len; ++$i) {
$password .= $alphabet[ord($random[$i]) % $alphabet_length];
}
或者,通常更好,是使用RandomLib和SecurityLib:
use SecurityLib\Strength;
$factory = new RandomLib\Factory;
$generator = $factory->getGenerator(new Strength(Strength::MEDIUM));
$password = $generator->generateString(12, $alphabet);
以下是生成随机字符串的最简短方法
<?php
echo $my_rand_strng = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), -15);
echo substr(md5(rand()), 0, 7);
echo str_shuffle(MD5(microtime()));
?>
我已经测试了那里最流行的功能的性能,在我的盒子上生成1'000'000个32个符号的字符串所需的时间是:
2.5 $s = substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,32);
1.9 $s = base64_encode(openssl_random_pseudo_bytes(24));
1.68 $s = bin2hex(openssl_random_pseudo_bytes(16));
0.63 $s = base64_encode(random_bytes(24));
0.62 $s = bin2hex(random_bytes(16));
0.37 $s = substr(md5(rand()), 0, 32);
0.37 $s = substr(md5(mt_rand()), 0, 32);
请注意它确实存在多长时间并不重要但速度较慢哪一个更快,因此您可以根据您的要求进行选择,包括加密准备等。
为了准确起见,添加了MD5周围的substr(),如果你需要短于32个符号的字符串。
为了回答:字符串没有连接但是被覆盖,并且没有存储函数的结果。
function rndStr($len = 64) {
$randomData = file_get_contents('/dev/urandom', false, null, 0, $len) . uniqid(mt_rand(), true);
$str = substr(str_replace(array('/','=','+'),'', base64_encode($randomData)),0,$len);
return $str;
}
这张照片取自adminer sources:
/** Get a random string
* @return string 32 hexadecimal characters
*/
function rand_string() {
return md5(uniqid(mt_rand(), true));
}
Adminer,用PHP编写的数据库管理工具。
一种非常快捷的方法是做一些事情:
substr(md5(rand()),0,10);
这将生成一个长度为10个字符的随机字符串。当然,有些人可能会说它在计算方面有点沉重,但现在处理器已经过优化,可以非常快速地运行md5或sha256算法。当然,如果rand()
函数返回相同的值,结果将是相同的,具有1/32767的相同概率。如果安全问题,那么只需将rand()
更改为mt_rand()
Laravel 5框架中的Helper功能
/**
* Generate a "random" alpha-numeric string.
*
* Should not be considered sufficient for cryptography, etc.
*
* @param int $length
* @return string
*/
function str_random($length = 16)
{
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
return substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
}
/**
* @param int $length
* @param string $abc
* @return string
*/
function generateRandomString($length = 10, $abc = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
{
return substr(str_shuffle($abc), 0, $length);
}
来自http://www.xeweb.net/2011/02/11/generate-a-random-string-a-z-0-9-in-php/的消息来源
该函数的编辑版本工作正常,但我发现只有一个问题:您使用了错误的字符来包含$字符,因此'字符有时是生成的随机字符串的一部分。
要解决此问题,请更改:
$characters = ’0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;
至:
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
这样,只使用包含的字符,'字符永远不会是生成的随机字符串的一部分。
注意:
str_shuffle()
内部使用rand()
,它不适用于加密目的(例如生成随机密码)。你想要一个secure random number generator。它也不允许重复字符。
UPDATED(现在生成任意长度的字符串):
function generateRandomString($length = 10) {
return substr(str_shuffle(str_repeat($x='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length/strlen($x)) )),1,$length);
}
echo generateRandomString(); // OR: generateRandomString(24)
而已。 :)
另一个单行,生成一个10个字符的随机字符串,带有字母和数字。它将使用range
创建一个数组(调整第二个参数来设置大小),循环遍历此数组并分配一个随机的ASCII字符(范围0-9或a-z),然后内爆数组以获取字符串。
$str = implode('', array_map(function () { return chr(rand(0, 1) ? rand(48, 57) : rand(97, 122)); }, range(0, 9)));
注意:这仅适用于PHP 5.3及更高版本
一个班轮。
对于具有一些独特性的巨大字符串来说,它很快。
function random_string($length){
return substr(str_repeat(md5(rand()), ceil($length/32)), 0, $length);
}
我喜欢使用openssl_random_pseudo_bytes的最后一条评论,但它不是我的解决方案,因为我仍然需要删除我不想要的字符,而且我无法获得设置长度的字符串。这是我的解决方案......
function rndStr($len = 20) {
$rnd='';
for($i=0;$i<$len;$i++) {
do {
$byte = openssl_random_pseudo_bytes(1);
$asc = chr(base_convert(substr(bin2hex($byte),0,2),16,10));
} while(!ctype_alnum($asc));
$rnd .= $asc;
}
return $rnd;
}
function randomString($length = 5) {
return substr(str_shuffle(implode(array_merge(range('A','Z'), range('a','z'), range(0,9)))), 0, $length);
}
在PHP中生成随机字符串的另一种方法是:
function RandomString($length) {
$original_string = array_merge(range(0,9), range('a','z'), range('A', 'Z'));
$original_string = implode("", $original_string);
return substr(str_shuffle($original_string), 0, $length);
}
echo RandomString(6);
仅使用PHP本机函数进行参数化单行程,自PHP 5.1.0开始工作
str_shuffle(implode('', (array_intersect_key(($map = array_map('chr', array_merge(array_map('mt_rand', array_fill(0, $length = 25, 48), array_fill(0,$length,57)),array_map('mt_rand', array_fill(0, $length, 65), array_fill(0,$length,90)),array_map('mt_rand', array_fill(0, $length, 97), array_fill(0,$length,122))))), array_flip($keys = array_rand($map, $length))))))
有简单的代码:
echo implode("",array_map(create_function('$s','return substr($s,mt_rand(0,strlen($s)),1);'),array_fill(0,16,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")));
有一个简单的指南:
16
更改为其他值。有更好的替代方案。许多已经发布,所以我只给你回复你的东西:
<?php
function RandomString()
{
global $randstring ;
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < 10; $i++) {
$randstring .= $characters[rand(0, strlen($characters))];
}
return $randstring;
}
RandomString();
echo $randstring;
?>
您可能也对以下内容感兴趣:
<?php
function RandomString()
{
global $randstring;
$characters = str_split('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
array_filter ($characters,function($var)use($characters,&$randstring){
$randstring .= $characters[rand(0, count($characters)-1)];
});
return $randstring;
}
RandomString();
echo $randstring.'<hr>';
//.. OR ..
$randstring = '';
echo(RandomString());
?>
或另一个:
<?php
function s($length){
for($i=0;
($i<$length) and
(
($what=rand(1,3))
and
(
(
($what==1) and
($t=rand(48, 57)
)
) or
(
($what==2) and
($t=rand(65, 90))
) or
(
($what==3) and
($t=rand(97, 122)
)
)
) and
(print chr($t))
);
$i++)
;
}
s(10);
?>
<?php
/**
* Creates a random string
*
* @param (int) $length
* Length in characters
* @param (array) $ranges
* (optional) Array of ranges to be used
*
* @return
* Random string
*/
function random_string($length, $ranges = array('0-9', 'a-z', 'A-Z')) {
foreach ($ranges as $r) $s .= implode(range(array_shift($r = explode('-', $r)), $r[1]));
while (strlen($s) < $length) $s .= $s;
return substr(str_shuffle($s), 0, $length);
}
// Examples:
$l = 100;
echo '<b>Default:</b> ' . random_string($l) . '<br />';
echo '<b>Lower Case only:</b> ' . random_string($l, array('a-z')) . '<br />';
echo '<b>HEX only:</b> ' . random_string($l, array('0-9', 'A-F')) . '<br />';
echo '<b>BIN only:</b> ' . random_string($l, array('0-1')) . '<br />';
/* End of file */
function getRandomString($length) {
$salt = array_merge(range('a', 'z'), range(0, 9));
$maxIndex = count($salt) - 1;
$result = '';
for ($i = 0; $i < $length; $i++) {
$index = mt_rand(0, $maxIndex);
$result .= $salt[$index];
}
return $result
}
这个问题有很多答案,但没有一个利用Cryptographically Secure Pseudo-Random Number Generator(CSPRNG)。
简单,安全,正确的答案是使用RandomLib而不是重新发明轮子。
对于那些坚持发明自己的解决方案的人,PHP 7.0.0将为此目的提供random_int()
;如果你还在PHP 5.x上,我们写了一个PHP 5 polyfill for random_int()
,所以你甚至可以在升级到PHP 7之前使用新的API。
Safely generating random integers in PHP不是一项微不足道的任务。在生产中部署本地算法之前,应始终使用your resident StackExchange cryptography experts进行检查。
使用安全的整数生成器,使用CSPRNG生成随机字符串就是在公园散步。
/**
* Generate a random string, using a cryptographically secure
* pseudorandom number generator (random_int)
*
* For PHP 7, random_int is a PHP core function
* For PHP 5.x, depends on https://github.com/paragonie/random_compat
*
* @param int $length How many characters do we want?
* @param string $keyspace A string of all possible characters
* to select from
* @return string
*/
function random_str($length, $keyspace = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
{
$pieces = [];
$max = mb_strlen($keyspace, '8bit') - 1;
for ($i = 0; $i < $length; ++$i) {
$pieces []= $keyspace[random_int(0, $max)];
}
return implode('', $pieces);
}
用法:
$a = random_str(32);
$b = random_str(8, 'abcdefghijklmnopqrstuvwxyz');
演示:https://3v4l.org/b4PST(忽略PHP 5失败;它需要random_compat)
以下是我如何获取真正的唯一随机密钥:
$Length = 10;
$RandomString = substr(str_shuffle(md5(time())), 0, $Length);
echo $RandomString;
你可以使用time(),因为它是一个Unix时间戳,并且与上面提到的其他随机数相比总是唯一的。然后,您可以生成md5sum,并从生成的MD5字符串中获取所需的长度。在这种情况下,我使用10个字符,如果我想让它更独特,我可以使用更长的字符串。
我希望这有帮助。
这将创建一个20个字符长的十六进制字符串:
$string = bin2hex(openssl_random_pseudo_bytes(10)); // 20 chars
在PHP 7(random_bytes())中:
$string = base64_encode(random_bytes(10)); // ~14 characters, includes /=+
// or
$string = substr(str_replace(['+', '/', '='], '', base64_encode(random_bytes(32))), 0, 32); // 32 characters, without /=+
// or
$string = bin2hex(random_bytes(10)); // 20 characters, only 0-9a-f
@tasmaniski:你的回答对我有用。我有同样的问题,我建议那些一直在寻找相同答案的人。这是来自@tasmaniski:
<?php
$random = substr(md5(mt_rand()), 0, 7);
echo $random;
?>
根据您的应用程序(我想生成密码),您可以使用
$string = base64_encode(openssl_random_pseudo_bytes(30));
作为base64,它们可能包含=
或-
以及请求的字符。您可以生成一个更长的字符串,然后过滤并修剪它以删除它们。
openssl_random_pseudo_bytes
似乎是在php中生成适当随机数的推荐方式。为什么rand
不使用/dev/random
我不知道。
这是一个简单的单行程序,它生成一个真正的随机字符串,没有任何脚本级别循环或使用OpenSSL库。
echo substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', mt_rand(1,10))), 1, 10);
将其分解以使参数清晰
// Character List to Pick from
$chrList = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
// Minimum/Maximum times to repeat character List to seed from
$chrRepeatMin = 1; // Minimum times to repeat the seed string
$chrRepeatMax = 10; // Maximum times to repeat the seed string
// Length of Random String returned
$chrRandomLength = 10;
// The ONE LINE random command with the above variables.
echo substr(str_shuffle(str_repeat($chrList, mt_rand($chrRepeatMin,$chrRepeatMax))), 1, $chrRandomLength);
此方法通过随机重复字符列表,然后混合组合字符串,并返回指定的字符数来工作。
您可以通过随机化返回的字符串的长度,将$chrRandomLength
替换为mt_rand(8, 15)
(对于8到15个字符之间的随机字符串)进一步随机化。
function generateRandomString($length = 15)
{
return substr(sha1(rand()), 0, $length);
}
然后!