我试图在PHP中创建一个随机字符串,我得到绝对没有输出:
<?php
function RandomString()
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < 10; $i++) {
$randstring = $characters[rand(0, strlen($characters))];
}
return $randstring;
}
RandomString();
echo $randstring;
我做错了什么?
我想要特定字符和预设长度的伪随机字符串。我希望当前版本的PHP具有最高质量的伪随机性,此时它可以是v5、v6、v7或v8,并且可以使用默认配置或特殊配置。为了解决这种混乱,我在这里选取了其他几个答案,并包含了函数可用性条件。
使用。要全局使用它,给$VALID_ID_CHARS赋值你想要的字符,然后调用它:
$VALID_ID_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
$myNewRandomId = makeId(6);
function makeId($desiredLen)
{
global $VALID_ID_CHARS;
if ($desiredLen < 1) {
throw new \RangeException("Length must be a positive integer");
}
$vLen = 0;
if (function_exists('mb_strlen')) {
$vLen = mb_strlen($VALID_ID_CHARS, '8bit') - 1;
} else {
$vLen = strlen($VALID_ID_CHARS) - 1;
}
if (function_exists('random_int')) {
$pieces = [];
for ($i = 0; $i < $desiredLen; ++$i) {
$pieces[] = $VALID_ID_CHARS[random_int(0, $vLen)];
}
return implode('', $pieces);
}
if (function_exists('openssl_random_pseudo_bytes')) {
$random = openssl_random_pseudo_bytes($desiredLen);
$id = '';
for ($i = 0; $i < $desiredLen; ++$i) {
$id .= $VALID_ID_CHARS[ord($random[$i]) % $vLen];
}
return $id;
}
http_response_code(500);
die('random id generation failed. either random_int or openssl_random_pseudo_bytes is needed');
}
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;
}
我总是喜欢使用base64来生成随机密码或其他随机(可打印的)字符串。base64的使用确保了大量的可打印字符可用。
在shell上,我通常这样做:
base64 < /dev/urandom |head -c10
在PHP中也可以做类似的事情。然而,直接从/dev/urandom读取可能会被open_basedir限制所禁止。这就是我得出的结论:
base64_encode(
join(
'',
array_map(
function($x){ return chr(mt_rand(1,255));},
range(1,15)
)
)
);
为了得到一个真正随机的字符串,我们也需要随机输入。这就是join/array_map所做的。使用uniqid之类的东西是不够的,因为它总是有一个类似的前缀,因为它基本上是一个美化的时间戳。
如果安装了openssl扩展,当然可以使用openssl_random_pseudo_bytes(),这样会更好。
你可以试试这个:
<?php
function random($len){
$char = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
// ----------------------------------------------
// Number of possible combinations
// ----------------------------------------------
$pos = strlen($char);
$pos = pow($pos, $len);
echo $pos.'<br>';
// ----------------------------------------------
$total = strlen($char)-1;
$text = "";
for ($i=0; $i<$len; $i++){
$text = $text.$char[rand(0, $total)];
}
return $text;
}
$string = random(15);
echo $string;
?>
您也可以准时使用md5,但要小心。
您需要使用microtime()而不是time()函数,因为如果多个线程在同一秒内运行,则需要为所有线程获取不同的字符串。
<?php
$string = md5(microtime());
echo $string;
?>
首先,定义你想要使用的字母:
$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);