我正在研究用于生成密码字符串的JS函数,它为a-z小写,A-Z大写,0-9和标点符号采用四个参数。我整理了一个基本字符串,如下所示:
function genpwd(azlc,azuc,num,pun,len) {
var chars = "";
if (azlc) chars += "abcdefghijklmnopqrstuvwxyz";
if (azuc) chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (num) chars += "012345678901234567890123";
if (pun) chars += "!@#%&()=?+-_.:,;*{}[]^$/";
然后我循环遍历基本字符串(给定密码长度)并随机挑出一个新字符串并将其作为输出密码返回。
for(i=0;i<len;i++) {
nextChar = chars.charAt(Math.floor(Math.random()*charsN));
password += nextChar;
}
return password;
}
这是生成随机字符串的一种非常简单的方法,但它不能保证每个“char group”中至少有一个char实际包含在输出字符串中。
我已经看了一些关于如何使用regexp的其他示例,但无法弄清楚如何修改它们以我想要的方式工作。我认为解决这个问题的“最简单”的方法可能就是使用正则表达式 - 就像这样:
if (password.magic_regexp_stuff) {
return password;
} else {
password = genpwd(azlc,azuc,num,pun,len);
}
好的,所以经过你们所有人的宝贵意见后,我最终得到了这个功能。
我也从mVChr的建议(感谢man!)切换到Py发布的那个,所以我很确定NobRuked指出的“统计问题”(没有任何其他的话)不会不再是一个问题。有人可以确认一下吗? :)
我还必须修改函数的参数和方法来处理要使用的字符集。有关改进的任何建议吗?
function passwd(len, azlc, azuc, num, pun) {
var len = parseInt(len),
ar = [],
checker = [],
passwd = '',
good = true,
num, num2,
sets = 0;
if(!len || len < 4) len = 12;
if(!azlc && !azuc && !num && !pun) { azlc = 1; azuc = 1; num = 1; pun = 1; }
if (azlc) {
ar.push("abcdefghijklmnopqrstuvwxyz");
checker.push(0);
sets++;
}
if (azuc) {
ar.push("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
checker.push(0);
sets++;
}
if (num) {
ar.push("0123456789");
checker.push(0);
sets++;
}
if (pun) {
ar.push("!@#%&()=?+-_.:,;*{}[]^$/");
checker.push(0);
sets++;
}
for (var i=0;i<len;i++){
num=rand(0,sets);
num2=rand(0,ar[num].length);
passwd+=ar[num][num2];
checker[num]=1;
}
for (var i=0;i<sets;i++){
if(checker[i]===0)
good=false;
}
if (good){
return passwd;
}
else{
return passwd(len);
}
}
非常感谢大家的帮助,非常感谢!
答案 0 :(得分:4)
我认为正则表达式不适合这项工作。您的尝试理论上可以永远循环(尽管极不可能),因为无法保证生成的密码与正则表达式匹配。
我想确保包含每个组中的一个字符的简单方法是明确地包含它。因此,假设您的密码长度至少为4个字符,我建议使用以下伪代码:
chars = charFrom(azlc) + charFrom(azuc) + charFrom(num) + charFrom(pun)
do the following, length_of_password - 4 times:
chars += charFrom(azlc + azuc + num + pun)
chars = shuffle(chars)
charFrom()
和shuffle()
的实施留给了读者。
答案 1 :(得分:2)
要使用正则表达式执行此操作,您实际上只需要(最多)四个正则表达式:
function genpwd(azlc,azuc,num,pun,len) {
var chars = "", regexs = [],
testRegexs = function(pw) {
var ii;
for (ii = 0; ii < regexs.length; ii += 1) {
if (!regexs[ii].test(pw)) {
return false;
}
return true;
}
};
if (azlc) {
chars += "abcdefghijklmnopqrstuvwxyz";
regexs.push(/[a-z]/);
}
if (azuc) {
chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
regexs.push(/[A-Z]/);
}
if (num) {
chars += "012345678901234567890123";
regexs.push(/0-9/);
}
if (pun) {
chars += "!@#%&()=?+-_.:,;*{}[]^$/";
regexs.push(/[\!\@\#\%\&\(\)\=\?\+\-\_\.\:\,\;\*\{\}\[\]\^\$\/]/);
}
do
{
// Generate a password...
}
while (!testRegexs(password));
return password;
}
答案 2 :(得分:1)
我会接受另一个approch。
我有4个字符串
lower = "abcdefghijklmnopqrstuvwxyz";
upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
num = "0123456789";
other = "!@#%&()=?+-_.:,;*{}[]^$/";
然后要生成密码,我将取0到3之间的随机整数,然后是0和选择字符串之间的另一个整数来取一个字符。
要检查是否已采取所有措施,我只需检查第一个随机选择中是否已采用4整数。
代码看起来像
function psswd(len){
var ar=[lower,upper,num,other],
checker=[0,0,0,0],
passwd="",
good=true,
num,num2;
for (var i=0;i<len;i++){
num=randomInt(0,3);
num2=randomInt(0,ar[num].length);
passwd+=ar[num][num2];
checker[num]=1;
}
for (var i=0;i<3;i++){
if(checker[i]===0)
good=false;
}
if (good){
return passwd;
}
else{
return psswd(len);
}
}
可能不是最佳,但不需要正则表达式。
答案 3 :(得分:1)
function genpwd(azlc,azuc,num,pun,len) {
var sets = [],
pw = [],
i, j, t;
if (azlc) sets.push("abcdefghijklmnopqrstuvwxyz");
if (azuc) sets.push("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
if (num) sets.push("0123456789");
if (pun) sets.push("!@#%&()=?+-_.:,;*{}[]^$/");
while (len) {
pw.push(sets[len%sets.length][~~(Math.random()*sets[len%sets.length].length)]);
len--;
}
i = pw.length;
while (--i) {
j = ~~(Math.random()*(i+1));
t = pw[j];
pw[j] = pw[i];
pw[i] = t;
}
return pw.join('');
}
编辑:添加了随机播放
答案 4 :(得分:0)
仅供记录,验证可以在一个正则表达式中完成:
/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[!@#%&()=?+_.:,;*{}\[\]^$\/-])/.test(mypassword)
关于密码生成方案,请参阅this。
答案 5 :(得分:0)
这是我的函数的最终版本(我还用一些信息更新了问题帖子)。
再次感谢大家的帮助! :)
/**
* Generate Password
* ---
* Generates a random text string containing characters types according to given
* parameters. Uses all character types by default. Output string length will at
* minimum be the number of character types currently in use.
*
* @param int Output string lenght
* @param bool Use letters a-z lower case
* @param bool Use letters A-Z upper case
* @param bool Use numbers 0-9
* @param bool Use punctuations (!@#$?*...)
* @return string Generated password string
*/
function genPwd(l,w,x,y,z){
var a=[],c=[],p='',g=true,n1,n2,s=0,i=0;
if(!w&&!x&&!y&&!z){w=1,x=1,y=1,z=1;}
if(w){c.push(0);s++;a.push("abcdefghijklmnopqrstuvwxyz");}
if(x){c.push(0);s++;a.push("ABCDEFGHIJKLMNOPQRSTUVWXYZ");}
if(y){c.push(0);s++;a.push("012345678901234567890123456789");}
if(z){c.push(0);s++;a.push("!@#%&/(){}[]=?+*^~-_.:,;");}
if(l<s){l=s;}for(i=0;i<l;i++){n1=Math.floor(Math.random()*(s-0));
n2=Math.floor(Math.random()*(a[n1].length-0));p+=a[n1][n2];c[n1]=1;}
for(i=0;i<s;i++){if(c[i]===0)g=false;}
if(g){return p;}else{return genPwd(l,w,x,y,z);}
}