在php中生成随机密码
Posted
技术标签:
【中文标题】在php中生成随机密码【英文标题】:Generating a random password in php 【发布时间】:2011-08-31 09:53:03 【问题描述】:我正在尝试在 php.ini 中生成一个随机密码。
但是我得到了所有的'a'并且返回类型是数组类型,我希望它是一个字符串。关于如何更正代码的任何想法?
谢谢。
function randomPassword()
$alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
for ($i = 0; $i < 8; $i++)
$n = rand(0, count($alphabet)-1);
$pass[$i] = $alphabet[$n];
return $pass;
【问题讨论】:
没有一个答案使用secure random number generator,你想用它作为密码。 访问者应该从可以正确更新的来源获得潜在的安全相关信息,而不是对新答案封闭的问题。我将删除此副本的答案,以便访问者改为阅读未解决问题的答案。 (如果这个问题被重新打开,答案将不会被删除。) @JeremyBanks 问题没有说明需要加密安全密码。对于某些人来说,使用/dev/random
的答案就足够了,因为该问题不要求输入“secure”密码(并且不应编辑以包含该密码,因为它会改变原始问题)。虽然我完全是为了安全,但我认为这个地毯炸弹并没有被充分考虑。与使用mysql_*
一样,答案仍然有效,但应标记为不安全。也许这是 SO 需要作为额外软件包含的东西 - 警告不安全代码的能力?
@JeremyBanks 你能恢复这个问题的答案吗?仅仅因为它是重复的,并不意味着答案是错误的(我不小心投票重新打开,我同意它是重复的)。删除答案是没有意义的,请考虑删除这个问题并将答案迁移到另一个问题(我以前见过它)。
@JeremyBanks 如果您不想重新打开某些内容,请将其锁定。否则 99% 的人会重新打开它并造成一团糟。就我个人而言,我完全不同意像这样删除高分答案,但不能为此与您抗衡
【参考方案1】:
安全警告:
rand()
不是加密安全的伪随机数生成器。在别处寻找generating a cryptographically secure pseudorandom string in PHP。
试试这个(使用strlen
而不是count
,因为字符串上的count
总是1
):
function randomPassword()
$alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
$pass = array(); //remember to declare $pass as an array
$alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
for ($i = 0; $i < 8; $i++)
$n = rand(0, $alphaLength);
$pass[] = $alphabet[$n];
return implode($pass); //turn the array into a string
Demo
【讨论】:
使用$pass .= $alphabet[$n]
似乎更直接。
使用 rand 生成 password 是一个非常糟糕的主意。这不是一个安全的 PRNG。 (没有mt_rand
也不是更好)
问题是关于生成密码。生成密码的代码显然需要使用安全的随机数。
出于与这不是重复问题相同的原因,这个答案是不正确的,因为问题是关于生成密码和不是 随机字符串。这个答案提供了一种非常不安全的方法来生成密码。请在下面使用@user3260409 的答案,其中使用openssl_random_pseudo_bytes()
而不是rand()
我已经看到您的不安全代码在生产中,并希望从源头上阻止它。您需要对密码的随机性进行加密保护。【参考方案2】:
TL;DR:
使用random_int()
和下面给定的random_str()
。
如果您没有random_int()
,请使用random_compat。
说明:
由于您正在生成 密码,因此您需要确保您生成的密码是不可预测的,并且确保此属性存在于您的实现中的唯一方法是使用 cryptographically secure pseudorandom number generator ( CSPRNG)。
对于随机字符串的一般情况,可以放宽对 CSPRNG 的要求,但在涉及安全性时则不能。
在 PHP 中生成密码的简单、安全和正确的答案是使用RandomLib,而不是重新发明***。这个库已经过行业安全专家以及我自己的审核。
对于喜欢发明自己的解决方案的开发人员,PHP 7.0.0 将为此提供random_int()
。如果您仍在使用 PHP 5.x,我们写了一个PHP 5 polyfill for random_int()
,以便您可以在 PHP 7 发布之前使用新的 API。使用我们的random_int()
polyfill可能比编写自己的实现更安全。
手头有一个安全的随机整数生成器,生成一个安全的随机字符串比饼图更容易:
<?php
/**
* 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'
)
$str = '';
$max = mb_strlen($keyspace, '8bit') - 1;
if ($max < 1)
throw new Exception('$keyspace must be at least two characters long');
for ($i = 0; $i < $length; ++$i)
$str .= $keyspace[random_int(0, $max)];
return $str;
【讨论】:
RandomLib 已经两年多没有更新了。在最近的 PHP 构建(在我的例子中是 7.1.25)上使用它会引发各种mcrypt_*
函数的弃用警告。我可以在an issue thread 上看到您拥有forked the library,因为无法获得@ircmaxell,但是您的fork 在 Travis 上说“构建失败”。您是否愿意更新这个答案(在 Google 上仍然显示很高)?
好收获!它需要被删除。【参考方案3】:
我知道您正在尝试以特定方式生成密码,但您可能也想查看此方法...
$bytes = openssl_random_pseudo_bytes(2);
$pwd = bin2hex($bytes);
它取自 php.net 站点,它创建的字符串长度是您在 openssl_random_pseudo_bytes 函数中输入的数字的两倍。所以上面会创建一个长度为 4 个字符的密码。
总之……
$pwd = bin2hex(openssl_random_pseudo_bytes(4));
将创建一个长度为 8 个字符的密码。
但请注意,密码仅包含数字 0-9 和小写字母 a-f!
【讨论】:
如果你想要一个大写、小写和数字的密码,试试这个:gist.github.com/zyphlar/7217f566fc83a9633959 @زياد 说谁?如果生成器使用 7 位字节,我会同意你的看法,但openssl_random_pseudo_bytes()
是一个强大的全二进制字节随机生成器,不需要任何进一步的改组。此外,我将借此机会指出,假设堆叠多种加密方法会使任何事情变得更加随机是很危险的,在某些情况下,由于累积的散列冲突,实际上可能正好相反。【参考方案4】:
2 行的小代码。
演示:http://codepad.org/5rHMHwnH
function rand_string( $length )
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return substr(str_shuffle($chars),0,$length);
echo rand_string(8);
您可以使用 rand_string 定义将创建多少字符。
【讨论】:
很好,尽管使用这种方法不会得到任何重复的字符,这可能是不可取的。 这个函数对于生成长密码很糟糕。首先,如果 $length 比 $chars 字符串长,那么您将不会收到与您输入的长度一样长的字符串,而是 chars 字符串的长度。此外,您只能保证每个字符中只有 1 个没有重复。它也不保证使用大写字母或数字,这通常是必需的(当然,除非您的长度由于先前的错误而超过 26) 这个@Programster 和@Hobo 怎么样?substr(str_shuffle(str_repeat($chars,$length)),0,$length);
@Charles-EdouardCoste 似乎工作得很好(特别是如果你加入一些特殊的字符)。尽管它仍然不保证每种字符类型中的至少一种。唯一困扰我的是通过所需密码的长度重复整个字符集,但这确保生成的密码中的字符不必是唯一的,并且在一次使用中不会对性能产生明显的影响。
我同意。最好不要根据行数选择算法。顺便说一句,如果主要目标只是在网站上创建新用户时生成一个临时密码,我想这可以满足需求。【参考方案5】:
如果您使用的是 PHP7,则可以使用 random_int()
函数:
function generate_password($length = 20)
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.
'0123456789`-=~!@#$%^&*()_+,./<>?;:[]\|';
$str = '';
$max = strlen($chars) - 1;
for ($i=0; $i < $length; $i++)
$str .= $chars[random_int(0, $max)];
return $str;
下面的旧答案:
function generate_password($length = 20)
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.
'0123456789`-=~!@#$%^&*()_+,./<>?;:[]\|';
$str = '';
$max = strlen($chars) - 1;
for ($i=0; $i < $length; $i++)
$str .= $chars[mt_rand(0, $max)];
return $str;
【讨论】:
不要使用mt_rand
生成密码。
@CodesInChaos 它比上面示例使用的 rand() 更好。根据 PHP 手册,首选 openssl_random_pseudo_bytes()。
@willbradley 种子的质量与mt_rand
一样糟糕,因此它仍然不适合任何安全用途。
你看这就是让我烦恼的 +ChaosInCodes。你没有看过这个问题,你只是做了一些笼统的陈述,重复了一堆不正确的信念。简而言之:针对完全不同的问题的正确建议。随机密码很好。它们可能仅用于“x”。老实说,如果您设计的系统没有定时锁定和 DOS 检测以及“x 尝试然后 -> 锁定”,那么您做错了。在采取此类措施的情况下,猜测 mt_rand 密码是不可能的。相反,使用 mt_rand 不会更容易暴力破解密码。它只是不会。
我不会在$chars
中使用\【参考方案6】:
一行:
substr(str_shuffle('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789') , 0 , 10 )
【讨论】:
这可以防止重复使用相同的字母,因为它们只是随机播放但不会出现多次。 不用说,没有人应该根据行数优化他们的密码生成功能。即使使用的 RNG 是安全的(它不是),在生成 10 个字符的密码时避免重复字符也会使您的熵从约 52 位降至约 50 位(破解速度快约 4 倍)。如果将其扩展到 20 个字符,则不重复将使您从 ~103 位降至 ~94 位(破解速度快 ~512 倍)。 这个方法让我想起了flaw in the Enigma codelolsubstr(str_shuffle(str_repeat($chars,$length)),0,$length);
熵恢复【参考方案7】:
您最好的选择是RandomLib library by ircmaxell。
使用示例:
$factory = new RandomLib\Factory;
$generator = $factory->getGenerator(new SecurityLib\Strength(SecurityLib\Strength::MEDIUM));
$passwordLength = 8; // Or more
$randomPassword = $generator->generateString($passwordLength);
它生成的字符串比shuffle()
和rand()
之类的普通随机函数更具有随机性(对于密码、盐和密钥等敏感信息,您通常需要这些函数)。
【讨论】:
这是正确答案。不要使用rand()
或mt_rand()
。
这可能是最安全的答案(不确定它与random_bytes
相比如何),但这并不意味着rand
的答案不正确。
rand
is not a good choice for passwords
@Cerbrus:当然这个答案并没有使使用rand()
的答案不正确。它们本身就是不正确的!【参考方案8】:
我将发布一个答案,因为一些现有答案很接近,但有一个:
比您想要的更小的字符空间,以便暴力破解更容易,或者密码必须更长才能获得相同的熵 RNG 不被视为加密安全 对某些 3rd 方库的要求,我认为展示自己可能需要做的事情可能会很有趣这个答案将绕过count/strlen
问题,因为生成的密码的安全性,至少恕我直言,超越了你如何到达那里。我还将假设 PHP > 5.3.0。
让我们把问题分解成几个组成部分:
-
使用一些安全的随机源来获取随机数据
使用该数据并将其表示为一些可打印的字符串
对于第一部分,PHP > 5.3.0 提供了函数openssl_random_pseudo_bytes
。请注意,虽然大多数系统使用加密强算法,但您必须进行检查,以便我们使用包装器:
/**
* @param int $length
*/
function strong_random_bytes($length)
$strong = false; // Flag for whether a strong algorithm was used
$bytes = openssl_random_pseudo_bytes($length, $strong);
if ( ! $strong)
// System did not use a cryptographically strong algorithm
throw new Exception('Strong algorithm not available for PRNG.');
return $bytes;
对于第二部分,我们将使用base64_encode
,因为它需要一个字节字符串,并且会生成一系列字符,其字母表与原始问题中指定的字母表非常接近。如果我们不介意在最终字符串中出现+
、/
和=
字符,并且我们希望结果至少有$n
个字符长,我们可以简单地使用:
base64_encode(strong_random_bytes(intval(ceil($n * 3 / 4))));
3/4
因素是由于 base64 编码产生的字符串长度至少比字节字符串大三分之一。对于$n
,结果将是精确的,它是 4 的倍数,否则最多长 3 个字符。由于额外的字符主要是填充字符=
,如果我们出于某种原因限制密码的长度是精确的,那么我们可以将其截断为我们想要的长度。这尤其是因为对于给定的 $n
,所有密码都将以相同数量的密码结尾,因此有权访问结果密码的攻击者最多可以少 2 个字符来猜测。
为了获得额外的荣誉,如果我们想要满足 OP 问题中的确切规范,那么我们将不得不做更多的工作。我将在这里放弃基本转换方法,并采用一种快速而肮脏的方法。由于 62 个条目的长字母表,两者都需要产生比结果中使用的更多的随机性。
对于结果中多余的字符,我们可以简单地将它们从结果字符串中丢弃。如果我们从字节字符串中的 8 个字节开始,那么大约 25% 的 base64 字符将是这些“不受欢迎的”字符,因此简单地丢弃这些字符会产生一个不短于 OP 所需的字符串。然后我们可以简单地截断它以得到确切的长度:
$dirty_pass = base64_encode(strong_random_bytes(8)));
$pass = substr(str_replace(['/', '+', '='], ['', '', ''], $dirty_pass, 0, 8);
如果您生成更长的密码,填充字符 =
在中间结果中的比例会越来越小,这样您就可以实施更精简的方法,前提是要考虑耗尽用于 PRNG 的熵池。
【讨论】:
感谢您的加入。现有答案均未指出openssl_random_pseudo_bytes
可能会产生较弱的结果。我没有意识到是这样的。【参考方案9】:
你想要strlen($alphabet)
,而不是常量alphabet
(相当于'alphabet'
)的count
。
但是,rand
不是用于此目的的合适随机函数。它的输出可以很容易地预测,因为它是隐含在当前时间播种的。此外,rand
不是加密安全的;因此,从输出中确定其内部状态相对容易。
相反,从/dev/urandom
读取以获取加密随机数据。
【讨论】:
【参考方案10】:base_convert(uniqid('pass', true), 10, 36);
例如。 e0m6ngefmj4
编辑
正如我在 cmets 中提到的,长度意味着蛮力攻击比定时攻击更有效,因此不必担心“随机生成器的安全性”。安全性,特别是对于这个用例,需要补充可用性,因此上述解决方案实际上足以解决所需的问题。
但是,以防万一您在搜索安全的随机字符串生成器时偶然发现了这个答案(我假设有些人基于响应),对于诸如生成令牌之类的东西,以下是此类代码生成器的方式看起来像:
function base64urlEncode($data)
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
function secureId($length = 32)
if (function_exists('openssl_random_pseudo_bytes'))
$bytes = openssl_random_pseudo_bytes($length);
return rtrim(strtr(base64_encode($bytes), '+/', '0a'), '=');
else // fallback to system bytes
error_log("Missing support for openssl_random_pseudo_bytes");
$pr_bits = '';
$fp = @fopen('/dev/urandom', 'rb');
if ($fp !== false)
$pr_bits .= @fread($fp, $length);
@fclose($fp);
if (strlen($pr_bits) < $length)
error_log('unable to read /dev/urandom');
throw new \Exception('unable to read /dev/urandom');
return base64urlEncode($pr_bits);
【讨论】:
PS - 这是 PHP - 只是使用 \ 来表示全局命名空间。 除了 uniqid 不是加密安全的。使用 rand() 代替:base_convert(rand(78364164096, 2821109907455), 10, 36); 根据 PHP 手册,@Benubird rand() 也不是加密安全的。手册建议改为 openssl_random_pseudo_bytes()。 对于大多数用例,特别是在攻击者无法访问确切时间的情况下,这完全没问题,并且会产生一个或多或少对人类友好的“临时”密码。如果我们把这个发挥到极致,这里的长度就麻烦多了,那么用什么函数来生成随机数。 我为感兴趣的人添加了一个生成完全安全字符串的示例;但强烈建议不要在为用户生成临时密码时使用它。即使使用安全版本,长度问题仍然存在。【参考方案11】:变得更聪明一点:
function strand($length)
if($length > 0)
return chr(rand(33, 126)) . strand($length - 1);
检查here。
【讨论】:
【参考方案12】:另一个(仅限 Linux)
function randompassword()
$fp = fopen ("/dev/urandom", 'r');
if (!$fp) die ("Can't access /dev/urandom to get random data. Aborting.");
$random = fread ($fp, 1024); # 1024 bytes should be enough
fclose ($fp);
return trim (base64_encode ( md5 ($random, true)), "=");
【讨论】:
读取 1024 字节压缩成 128 位的熵加密散列有点浪费。此外,fread()
默认缓冲为 8192 字节,因此您总是会使用给定的代码从/dev/urandom
读取那么多字节。这也不适用于 Windows。不过,感谢使用 CSPRNG。【参考方案13】:
尝试使用大写字母、小写字母、数字和特殊字符
function generatePassword($_len)
$_alphaSmall = 'abcdefghijklmnopqrstuvwxyz'; // small letters
$_alphaCaps = strtoupper($_alphaSmall); // CAPITAL LETTERS
$_numerics = '1234567890'; // numerics
$_specialChars = '`~!@#$%^&*()-_=+][;:,<.>/?\'"\|'; // Special Characters
$_container = $_alphaSmall.$_alphaCaps.$_numerics.$_specialChars; // Contains all characters
$password = ''; // will contain the desired pass
for($i = 0; $i < $_len; $i++) // Loop till the length mentioned
$_rand = rand(0, strlen($_container) - 1); // Get Randomized Length
$password .= substr($_container, $_rand, 1); // returns part of the string [ high tensile strength ;) ]
return $password; // Returns the generated Pass
假设我们需要 10 位通行证
echo generatePassword(10);
示例输出:
,IZCQ_IV\7
@wlqsfhT(d
1!8+1\4@uD
【讨论】:
rand
函数实际上在密码学上并不安全,因此使用它生成密码可能会有很大风险【参考方案14】:
使用这个简单的代码生成 12 长的中等强度密码
$password_string = '!@#$%*&abcdefghijklmnpqrstuwxyzABCDEFGHJKLMNPQRSTUWXYZ23456789';
$password = substr(str_shuffle($password_string), 0, 12);
【讨论】:
这实际上是(非常?)错误的。它实际上只使用字母表中的每个字符一次,因此严重缩小了所有可能值的空间(与破解相关)。【参考方案15】:快一。简单、干净和一致的格式,如果你想要的话
$pw = chr(mt_rand(97,122)).mt_rand(0,9).chr(mt_rand(97,122)).mt_rand(10,99).chr(mt_rand(97,122)).mt_rand(100,999);
【讨论】:
【参考方案16】:这是基于此页面上的另一个答案,https://***.com/a/21498316/525649
这个答案只生成十六进制字符0-9,a-f
。对于看起来不像十六进制的东西,试试这个:
str_shuffle(
rtrim(
base64_encode(bin2hex(openssl_random_pseudo_bytes(5))),
'='
).
strtoupper(bin2hex(openssl_random_pseudo_bytes(7))).
bin2hex(openssl_random_pseudo_bytes(13))
)
base64_encode
返回更广泛的字母数字字符
rtrim
有时会在末尾删除 =
例子:
32eFVfGDg891Be5e7293e54z1D23110M3ZU3FMjb30Z9a740Ej0jz4
b280R72b48eOm77a25YCj093DE5d9549Gc73Jg8TdD9Z0Nj4b98760
051b33654C0Eg201cfW0e6NA4b9614ze8D2FN49E12Y0zY557aUCb8
y67Q86ffd83G0z00M0Z152f7O2ADcY313gD7a774fc5FF069zdb5b7
这对于为用户创建界面并不是非常可配置的,但出于某些目的是可以的。增加字符数以解决缺少特殊字符的问题。
【讨论】:
【参考方案17】:-
创建一个包含此代码的文件。
像在 cmets 中那样称呼它。
<?php
/**
* @usage :
* include_once($path . '/Password.php');
* $Password = new Password;
* $pwd = $Password->createPassword(10);
* return $pwd;
*
*/
class Password
public function createPassword($length = 15)
$response = [];
$response['pwd'] = $this->generate($length);
$response['hashPwd'] = $this->hashPwd( $response['pwd'] );
return $response;
private function generate($length = 15)
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()/?,><";
return substr(str_shuffle($chars),0,$length);
private function hashPwd($pwd)
return hash('sha256', $pwd);
?>
【讨论】:
【参考方案18】:我创建了一个更全面、更安全的密码脚本。这将创建两个大写字母、两个小写字母、两个数字和两个特殊字符的组合。共 8 个字符。
$char = [range('A','Z'),range('a','z'),range(0,9),['*','%','$','#','@','!','+','?','.']];
$pw = '';
for($a = 0; $a < count($char); $a++)
$randomkeys = array_rand($char[$a], 2);
$pw .= $char[$a][$randomkeys[0]].$char[$a][$randomkeys[1]];
$userPassword = str_shuffle($pw);
【讨论】:
【参考方案19】://define a function. It is only 3 lines!
function generateRandomPassword($length = 5)
$chars = "0123456789bcdfghjkmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
return substr(str_shuffle($chars),0,$length);
//usage
echo generateRandomPassword(5); //random password legth: 5
echo generateRandomPassword(6); //random password legth: 6
echo generateRandomPassword(7); //random password legth: 7
【讨论】:
这实际上是(非常?)错误的。它实际上只使用字母表中的每个字符一次,因此严重缩小了所有可能值的空间(与破解相关)。【参考方案20】:我的回答和上面的一些类似,但是我去掉了元音、数字 1 和 0、字母 i、j、I、l、O、o、Q、q、X、x、Y、y、W、 w。原因是:第一个很容易混淆(如 l 和 1,取决于字体),其余的(以 Q 开头)是因为它们在我的语言中不存在,所以它们可能有点奇怪超级终端用户。字符串仍然足够长。另外,我知道使用一些特殊标志会很理想,但它们也无法与某些最终用户相处。
function generatePassword($length = 8)
$chars = '23456789bcdfhkmnprstvzBCDFHJKLMNPRSTVZ';
$shuffled = str_shuffle($chars);
$result = mb_substr($shuffled, 0, $length);
return $result;
另外,通过这种方式,我们避免重复相同的字母和数字(不包括匹配大小写)
【讨论】:
【参考方案21】:这是我对选项列表的贡献。
此功能可确保满足密码策略。
function password_generate($length=8, $min_lowercases=1, $min_uppercases=1, $min_numbers=1, $min_specials=0)
$lowercases = 'abcdefghijklmnopqrstuvwxyz';
$uppercases = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$numbers = '0123456789';
$specials = '!#%&/()[]+-';
$absolutes = '';
if ($min_lowercases && !is_bool($min_lowercases)) $absolutes .= substr(str_shuffle(str_repeat($lowercases, $min_lowercases)), 0, $min_lowercases);
if ($min_uppercases && !is_bool($min_uppercases)) $absolutes .= substr(str_shuffle(str_repeat($uppercases, $min_uppercases)), 0, $min_uppercases);
if ($min_numbers && !is_bool($min_numbers)) $absolutes .= substr(str_shuffle(str_repeat($numbers, $min_numbers)), 0, $min_numbers);
if ($min_specials && !is_bool($min_specials)) $absolutes .= substr(str_shuffle(str_repeat($specials, $min_specials)), 0, $min_specials);
$remaining = $length - strlen($absolutes);
$characters = '';
if ($min_lowercases !== false) $characters .= substr(str_shuffle(str_repeat($lowercases, $remaining)), 0, $remaining);
if ($min_uppercases !== false) $characters .= substr(str_shuffle(str_repeat($uppercases, $remaining)), 0, $remaining);
if ($min_numbers !== false) $characters .= substr(str_shuffle(str_repeat($numbers, $remaining)), 0, $remaining);
if ($min_specials !== false) $characters .= substr(str_shuffle(str_repeat($specials, $remaining)), 0, $remaining);
$password = str_shuffle($absolutes . substr($characters, 0, $remaining));
return $password;
$min_* 参数可以有以下值:
1-999 = 必需 真 = 可选 false = 禁用可以这样使用:
echo password_generate(8); // Outputs a random 8 characters long password
10 个字符的密码,每组至少包含 2 个字符:
echo password_generate(10, 2, 2, 2, 2);
仅输出 6 个随机数
echo password_generate(6, false, false, true, false);
【讨论】:
【参考方案22】:生成长度为 8 的强密码,其中至少包含一个小写字母、一个大写字母、一个数字和一个特殊字符。您也可以更改代码中的长度。
function checkForCharacterCondition($string)
return (bool) preg_match('/(?=.*([A-Z]))(?=.*([a-z]))(?=.*([0-9]))(?=.*([~`\!@#\$%\^&\*\(\)_\\\[\]]))/', $string);
$j = 1;
function generate_pass()
global $j;
$allowedCharacters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_[]';
$pass = '';
$length = 8;
$max = mb_strlen($allowedCharacters, '8bit') - 1;
for ($i = 0; $i < $length; ++$i)
$pass .= $allowedCharacters[random_int(0, $max)];
if (checkForCharacterCondition($pass))
return '<br><strong>Selected password: </strong>'.$pass;
else
echo 'Iteration '.$j.': <strong>'.$pass.'</strong> Rejected<br>';
$j++;
return generate_pass();
echo generate_pass();
【讨论】:
【参考方案23】:此函数将根据参数中的规则生成密码
function random_password( $length = 8, $characters = true, $numbers = true, $case_sensitive = true, $hash = true )
$password = '';
if($characters)
$charLength = $length;
if($numbers) $charLength-=2;
if($case_sensitive) $charLength-=2;
if($hash) $charLength-=2;
$chars = "abcdefghijklmnopqrstuvwxyz";
$password.= substr( str_shuffle( $chars ), 0, $charLength );
if($numbers)
$numbersLength = $length;
if($characters) $numbersLength-=2;
if($case_sensitive) $numbersLength-=2;
if($hash) $numbersLength-=2;
$chars = "0123456789";
$password.= substr( str_shuffle( $chars ), 0, $numbersLength );
if($case_sensitive)
$UpperCaseLength = $length;
if($characters) $UpperCaseLength-=2;
if($numbers) $UpperCaseLength-=2;
if($hash) $UpperCaseLength-=2;
$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$password.= substr( str_shuffle( $chars ), 0, $UpperCaseLength );
if($hash)
$hashLength = $length;
if($characters) $hashLength-=2;
if($numbers) $hashLength-=2;
if($case_sensitive) $hashLength-=2;
$chars = "!@#$%^&*()_-=+;:,.?";
$password.= substr( str_shuffle( $chars ), 0, $hashLength );
$password = str_shuffle( $password );
return $password;
【讨论】:
【参考方案24】:这是我对随机纯密码生成助手的看法。
确保密码包含数字、大小写字母以及最少 3 个特殊字符。
密码长度在 11 到 30 之间。
function plainPassword(): string
$numbers = array_rand(range(0, 9), rand(3, 9));
$uppercase = array_rand(array_flip(range('A', 'Z')), rand(2, 8));
$lowercase = array_rand(array_flip(range('a', 'z')), rand(3, 8));
$special = array_rand(array_flip(['@', '#', '$', '!', '%', '*', '?', '&']), rand(3, 5));
$password = array_merge(
$numbers,
$uppercase,
$lowercase,
$special
);
shuffle($password);
return implode($password);
【讨论】:
【参考方案25】:生成随机密码字符串
function generate_randompassword($passlength = 8)
$alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#%^*>\$@?/[]=+';
$pass = array(); //remember to declare $pass as an array
$alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
for ($i = 0; $i < $passlength; $i++)
$n = rand(0, $alphaLength);
$pass[] = $alphabet[$n];
return implode($pass); //turn the array into a string
【讨论】:
【参考方案26】:function password_generate($n, $l, $s)
$numbers = '1234567890';
$letters = '1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcefghijklmnopqrstuvwxyz';
$special = '--!=!@@#++%';
return substr(str_shuffle($numbers), 0, $n).substr(str_shuffle($letters), 0, $l).substr(str_shuffle($special), 0, $s);
echo password_generate(2,9,1);
【讨论】:
出于密码生成目的,只能使用安全随机生成器,例如random_bytes
或random_int
。许多其他随机值生成解决方案,包括涉及time()
、microtime()
、uniqid()
、rand()
、mt_rand()
、str_shuffle()
、array_rand()
和shuffle()
的解决方案,都更加可预测,并且如果随机字符串将用作密码或其他秘密值,则不适合。见:***.com/questions/4570980/…以上是关于在php中生成随机密码的主要内容,如果未能解决你的问题,请参考以下文章