在php中生成随机密码
我正在尝试在 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;
}
I am trying to generate a random password in php.
However I am getting all 'a's and the return type is of type array and I would like it to be a string. Any ideas on how to correct the code?
Thanks.
function randomPassword() {
$alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
for ($i = 0; $i < 8; $i++) {
$n = rand(0, count($alphabet)-1);
$pass[$i] = $alphabet[$n];
}
return $pass;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(30)
试试这个(使用
strlen
而不是count
,因为字符串上的count
始终为1
):演示
Try this (use
strlen
instead ofcount
, becausecount
on a string is always1
):Demo
TL;DR:
random_int()
和下面给定的random_str()
。random_int()
,请使用 random_compat。说明:
由于您要生成密码,因此需要确保生成的密码是不可预测的,并且确保此属性出现在您的实现中的唯一方法是使用 加密安全伪随机数生成器(CSPRNG)。
对于随机字符串的一般情况,可以放宽对 CSPRNG 的要求,但在涉及安全性时则不然。
在 PHP 中生成密码的简单、安全且正确的答案是使用 RandomLib 并且不要重新发明车轮。该库已经过行业安全专家以及我自己的审核。
对于喜欢发明自己的解决方案的开发人员,PHP 7.0.0 将提供
random_int()
为此目的。如果您仍在使用 PHP 5.x,我们为random_int() 编写了
PHP 5 polyfill
这样您就可以在 PHP 7 发布之前使用新的 API。使用我们的random_int()
polyfill可能比编写自己的实现更安全。有了安全随机整数生成器,生成安全随机字符串比馅饼更容易:
TL;DR:
random_int()
and the givenrandom_str()
below.random_int()
, use random_compat.Explanation:
Since you are generating a password, you need to ensure that the password you generate is unpredictable, and the only way to ensure this property is present in your implementation is to use a cryptographically secure pseudorandom number generator (CSPRNG).
The requirement for a CSPRNG can be relaxed for the general case of random strings, but not when security is involved.
The simple, secure, and correct answer to password generation in PHP is to use RandomLib and don't reinvent the wheel. This library has been audited by industry security experts, as well as myself.
For developers who prefer inventing your own solution, PHP 7.0.0 will provide
random_int()
for this purpose. If you're still on PHP 5.x, we wrote a PHP 5 polyfill forrandom_int()
so you can use the new API before PHP 7 is released. Using ourrandom_int()
polyfill is probably safer than writing your own implementation.With a secure random integer generator on hand, generating a secure random string is easier than pie:
我知道您正在尝试以特定方式生成密码,但您可能也想看看这个方法...
它取自 php.net 站点,它创建一个字符串,其长度是您输入的数字的两倍放入 openssl_random_pseudo_bytes 函数。因此上面将创建一个 4 个字符长的密码。
简而言之...
将创建一个 8 个字符长的密码。
但请注意,密码仅包含数字 0-9 和小写字母 af!
I know you are trying to generate your password in a specific way, but you might want to look at this method as well...
It's taken from the php.net site and it creates a string which is twice the length of the number you put in the openssl_random_pseudo_bytes function. So the above would create a password 4 characters long.
In short...
Would create a password 8 characters long.
Note however that the password only contains numbers 0-9 and small cap letters a-f!
2 行的小代码。
演示:http://codepad.org/5rHMHwnH
Tiny code with 2 line.
demo: http://codepad.org/5rHMHwnH
如果您使用的是 PHP7,则可以使用
random_int()
函数:If you are on PHP7 you could use the
random_int()
function:一行:
In one line:
您最好的选择是ircmaxell 的RandomLib 库。
用法示例:
它生成的字符串比普通随机函数(如
shuffle()
和rand()
)具有更强的随机性(这正是您通常需要的密码等敏感信息) 、盐和键)。Your best bet is the RandomLib library by ircmaxell.
Usage example:
It produces strings which are more strongly random than the normal randomness functions like
shuffle()
andrand()
(which is what you generally want for sensitive information like passwords, salts and keys).我将发布一个答案,因为现有的一些答案很接近,但具有以下之一:
这个答案将规避
count/strlen
问题,因为生成的密码的安全性(至少恕我直言)超越了您的实现方式。我还将假设 PHP > 5.3.0。让我们将问题分解为以下几个组成部分:
对于第一部分,PHP > 5.3.0 提供函数
openssl_random_pseudo_bytes
。请注意,虽然大多数系统使用加密强度较高的算法,但您必须进行检查,以便我们使用包装器:对于第二部分,我们将使用
base64_encode
因为它需要一个字节字符串,并且会生成一系列字符,这些字符的字母表非常接近于原来的问题。如果我们不介意最终字符串中出现+
、/
和=
字符,并且我们希望结果至少为$ n
个字符长,我们可以简单地使用:3/4
因子是由于 Base64 编码导致的字符串长度至少比字节字符串大三分之一。如果$n
是 4 的倍数且最多长 3 个字符,则结果将是准确的。由于额外的字符主要是填充字符=
,如果我们出于某种原因限制密码的长度是精确的,那么我们可以将其截断为我们想要的长度。这尤其是因为对于给定的$n
,所有密码都将以相同的数字结尾,因此有权访问结果密码的攻击者最多可以少 2 个字符进行猜测。为了额外的好处,如果我们想满足OP问题中的确切规格,那么我们将不得不做更多的工作。我将放弃这里的基本转换方法,并采用一种快速而肮脏的方法。由于字母表有 62 个条目,两者都需要生成比结果中使用的随机性更多的随机性。
对于结果中的额外字符,我们可以简单地将它们从结果字符串中丢弃。如果我们从字节串中的 8 个字节开始,那么最多大约 25% 的 Base64 字符将是这些“不需要的”字符,因此简单地丢弃这些字符会得到一个不短于 OP 所需的字符串。然后我们可以简单地截断它以达到精确的长度:
如果您生成更长的密码,填充字符
=
在中间结果中所占的比例越来越小,以便您可以实现更精简的方法,如果需要考虑耗尽用于 PRNG 的熵池。I'm going to post an answer because some of the existing answers are close but have one of:
This answer will circumvent the
count/strlen
issue as the security of the generated password, at least IMHO, transcends how you're getting there. I'm also going to assume PHP > 5.3.0.Let's break the problem down into the constituent parts which are:
For the first part, PHP > 5.3.0 provides the function
openssl_random_pseudo_bytes
. Note that whilst most systems use a cryptographically strong algorithm, you have to check so we'll use a wrapper:For the second part, we'll use
base64_encode
since it takes a byte string and will produce a series of characters that have an alphabet very close to the one specified in the original question. If we didn't mind having+
,/
and=
characters appear in the final string and we want a result at least$n
characters long, we could simply use:The
3/4
factor is due to the fact that base64 encoding results in a string that has a length at least a third bigger than the byte string. The result will be exact for$n
being a multiple of 4 and up to 3 characters longer otherwise. Since the extra characters are predominantly the padding character=
, if we for some reason had a constraint that the password be an exact length, then we can truncate it to the length we want. This is especially because for a given$n
, all passwords would end with the same number of these, so that an attacker who had access to a result password, would have up to 2 less characters to guess.For extra credit, if we wanted to meet the exact spec as in the OP's question then we would have to do a little bit more work. I'm going to forgo the base conversion approach here and go with a quick and dirty one. Both need to generate more randomness than will be used in the result anyway because of the 62 entry long alphabet.
For the extra characters in the result, we can simply discard them from the resulting string. If we start off with 8 bytes in our byte-string, then up to about 25% of the base64 characters would be these "undesirable" characters, so that simply discarding these characters results in a string no shorter than the OP wanted. Then we can simply truncate it to get down to the exact length:
If you generate longer passwords, the padding character
=
forms a smaller and smaller proportion of the intermediate result so that you can implement a leaner approach, if draining the entropy pool used for the PRNG is a concern.您需要
strlen($alphabet)
,而不是常量alphabet
的count
(相当于'alphabet'
)。但是,
rand
不是适合此目的的随机函数。它的输出可以很容易地预测,因为它隐式地以当前时间为种子。此外,rand
在加密上并不安全;因此,从输出确定其内部状态相对容易。相反,从
/dev/urandom
读取以获取加密随机数据。You want
strlen($alphabet)
, notcount
of the constantalphabet
(equivalent to'alphabet'
).However,
rand
is not a suitable random function for this purpose. Its output can easily be predicted as it is implicitly seeded with the current time. Additionally,rand
is not cryptographically secure; it is therefore relatively easy to determine its internal state from output.Instead, read from
/dev/urandom
to get cryptographically random data.聪明一点:
在此处在线查看。
Being a little smarter:
check it here online.
base_convert(uniqid('pass', true), 10, 36);
例如。
e0m6ngefmj4
编辑
正如我在评论中提到的,长度意味着暴力攻击比定时攻击更有效,因此不必担心“安全性如何”随机生成器是。”专门针对此用例的安全性需要补充可用性,因此上述解决方案实际上足以解决所需的问题。
然而,以防万一您在搜索安全随机字符串生成器时偶然发现了这个答案(我假设有些人基于响应),对于生成令牌之类的东西,以下是此类代码的生成器的样子:
base_convert(uniqid('pass', true), 10, 36);
eg.
e0m6ngefmj4
EDIT
As I've mentioned in comments, the length means that brute force attacks would work better against it then timing attacks so it's not really relevant to worry about "how secure the random generator was." Security, specifically for this use case, needs to complement usability so the above solution is actually good enough for the required problem.
However, just in case you stumbled upon this answer while searching for a secure random string generator (as I assume some people have based on the responses), for something such as generating tokens, here is how a generator of such codes would look like:
另一种(仅限 Linux)
Another one (linux only)
尝试使用大写字母、小写字母、数字和特殊字符
示例输出:
,IZCQ_IV\7
@wlqsfhT(d
1!8+1\4@uD
Try This with Capital Letters, Small Letters, Numeric(s) and Special Characters
Example Output(s) :
,IZCQ_IV\7
@wlqsfhT(d
1!8+1\4@uD
使用这个简单的代码生成 12 长度的中等强密码
Use this simple code for generate med-strong password 12 length
这是我对选项列表的贡献。
此功能可确保满足密码策略。
$min_* 参数可以具有以下值:
它可以按如下方式使用:
10 个字符的密码,每组至少有 2 个字符:
仅输出 6 个随机数
Here is my contribution to the list of options.
This function ensures that the password policy is met.
The $min_* parameters can have the following values:
It can be used like the following:
A 10 character password with a minimum of 2 charcaters from each set:
Output 6 random numbers only
快一号。简单、干净、一致的格式(如果这是您想要的)
Quick One. Simple, clean and consistent format if that is what you want
这是基于本页上的另一个答案, https://stackoverflow.com/a/21498316/525649
此答案生成只是十六进制字符,
0-9,af
。对于看起来不像十六进制的内容,请尝试以下操作:base64_encode
返回更广泛的字母数字字符rtrim
有时会删除末尾的=
示例:
y67Q86ffd83G0z00M0Z152f7O2ADcY313gD7a774fc5FF069zdb5b7
这对于创建界面来说不是很好配置,但对于某些目的没关系。增加字符数以解决特殊字符的缺失问题。
This is based off another answer on this page, https://stackoverflow.com/a/21498316/525649
This answer generates just hex characters,
0-9,a-f
. For something that doesn't look like hex, try this:base64_encode
returns a wider spread of alphanumeric charsrtrim
removes the=
sometimes at the endExamples:
32eFVfGDg891Be5e7293e54z1D23110M3ZU3FMjb30Z9a740Ej0jz4
b280R72b48eOm77a25YCj093DE5d9549Gc73Jg8TdD9Z0Nj4b98760
051b33654C0Eg201cfW0e6NA4b9614ze8D2FN49E12Y0zY557aUCb8
y67Q86ffd83G0z00M0Z152f7O2ADcY313gD7a774fc5FF069zdb5b7
This isn't very configurable for creating an interface for users, but for some purposes that's okay. Increase the number of chars to account for the lack of special characters.
像评论中那样称呼它。
<前><代码>createPassword(10);
* 返回$pwd;
*
*/
类密码{
公共函数createPassword($length = 15) {
$响应=[];
$response['pwd'] = $this->generate($length);
$response['hashPwd'] = $this->hashPwd( $response['pwd'] );
返回$响应;
}
私有函数生成($length = 15) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*(){}/?,><";
返回 substr(str_shuffle($chars),0,$length);
}
私有函数 hashPwd($pwd) {
返回哈希('sha256',$pwd);
}
}
?>
Call it like in the comments.
我创建了一个更全面、更安全的密码脚本。这将创建两个大写字母、两个小写字母、两个数字和两个特殊字符的组合。共8个字符。
I created a more comprehensive and secure password script. This will create a combination of two uppercase, two lowercase, two numbers and two special characters. Total 8 characters.
我的答案与上面的一些类似,但我删除了元音、数字 1 和 0、字母 i,j, I, l, O,o, Q, q, X,x,Y,y,W,w。原因是:第一个很容易混淆(例如 l 和 1,具体取决于字体),其余的(以 Q 开头)是因为它们在我的语言中不存在,所以它们对于我来说可能有点奇怪超级终端用户。字符串还是够长的。另外,我知道使用一些特殊标志是理想的,但它们也与某些最终用户相处不好。
另外,通过这种方式,我们可以避免重复相同的字母和数字(不包括匹配大小写)
My answer is similar to some of the above, but I removed vowels, numbers 1 and 0, letters i,j, I, l, O,o, Q, q, X,x,Y,y,W,w. The reason is: the first ones are easy to mix up (like l and 1, depending on the font) and the rest (starting with Q) is because they don't exist in my language, so they might be a bit odd for super-end users. The string of characters is still long enough. Also, I know it would be ideal to use some special signs, but they also don't get along with some end-users.
Also, in this way, we avoid repeating the same letters and digits (match case not included)
一个简单的代码应该像:
输出:
A simple code should be like :
output:
生成长度为 8 的强密码,其中至少包含 1 个小写字母、1 个大写字母、1 个数字和 1 个特殊字符。您也可以更改代码中的长度。
Generates a strong password of length 8 containing at least one lower case letter, one uppercase letter, one digit, and one special character. You can change the length in the code too.
这是我对随机纯密码生成助手的看法。
它确保密码包含数字、大小写字母以及至少 3 个特殊字符。
密码长度在 11 到 30 之间。
Here's my take at random plain password generation helper.
It ensures that password has numbers, upper and lower case letters as well as a minimum of 3 special characters.
Length of the password will be between 11 and 30.
生成随机密码字符串
Generate random password string
在我的例子中,我使用 uniqid();它根据当前时间(以微秒为单位)获取唯一的前缀值。这样就很难重复这个值,否则如果需要加密密码,也可以使用password_hash()。
按照示例:
或者只使用 uniqid();
有用的链接:
https://www.php.net/manual/en /function.password-hash.php
https://www.php.net/manual/pt_BR/function.uniqid.php
In my case I use uniqid(); it gets a unique prefixed value based on the current time in microseconds. In this way it is very difficult to repeat this value, otherwise you can also use password_hash(), if you need to encrypt the password.
Follow the examples:
Or just use uniqid();
Useful links:
https://www.php.net/manual/en/function.password-hash.php
https://www.php.net/manual/pt_BR/function.uniqid.php
该函数会根据参数中的规则生成密码
This function will generate a password based on the rules in parameters
这是我的密码助手
用法:
PasswordHelper::generatePassword()
或PasswordHelper::generatePassword(2,4,5,3)
Here is my password helper
usage:
PasswordHelper::generatePassword()
orPasswordHelper::generatePassword(2,4,5,3)
有一个简短的解决方案(php 8.1):
一行 bash 脚本:
php -r '$dict = array_merge(...array_map(fn(array $d): array => range(ord($d) [0]), ord($d[1])), [["0", "9"], ["a", "z"], ["A", "Z"]] )); $f = fn (int $len): 字符串 => join("", array_map(fn (): string => chr($dict[random_int(0, count($dict) - 1)]), range(0, $len) ));回声 $f(12) 。 PHP_EOL;'
这是来自 https://stackoverflow.com/a/41077923/5599052
There is one short solution (php 8.1):
one-line bash script:
php -r '$dict = array_merge(...array_map(fn(array $d): array => range(ord($d[0]), ord($d[1])), [["0", "9"], ["a", "z"], ["A", "Z"]] )); $f = fn (int $len): string => join("", array_map(fn (): string => chr($dict[random_int(0, count($dict) - 1)]), range(0, $len) )); echo $f(12) . PHP_EOL;'
This is developed idea from https://stackoverflow.com/a/41077923/5599052