javascript 使用顺序字母和数字进行密码验证- RegEx

xnifntxz  于 2023-04-28  发布在  Java
关注(0)|答案(5)|浏览(222)

为了使客户帐户更加安全,精心设计的密码是一种良好的做法。这是用于密码验证的正则表达式字符串。

/^(?=.*[0-9])(?!.*?\d{3})(?=.*[a-zA-Z])(?!.*?[a-zA-Z]{3})(?=.*[~!@#$%^&*()+-?])([a-zA-Z0-9~!@#$%^&*()+-?]{8,})$/

代表:

  • 8个或更多字符。
  • 大写字母A-Z
  • 小写字母a-z
  • 特殊人物~!@#$%^&*()+-?
  • 这个正则表达式函数是什么?不得包含多达3个连续字母和/或数字。

将数字和/或字母按顺序排列为3个或更多是不允许的。
示例:
不正常= efg 123!$,abcd567%,xyz789^&,#hijk23456

OK= ryiiu562@,erty745#,gjnfl45566

谢谢你

3zwtqj6y

3zwtqj6y1#

据我所知,没有办法使用RegEx,但这里有一个简单的函数式方法。
首先,循环遍历字符串,并将每个字符与接下来的两个字符进行比较,方法是在当前索引中添加+1和+2,并进行适当的比较。
其次,再次循环遍历字符串,并将接下来的两个字符与当前字符进行比较,以查看它们是否是连续的。
如果两个循环都未能找到连续字符,则函数返回true,否则返回false。
前四个返回false(失败),后三个返回true(通过)。

function test(s) {
    // Check for sequential numerical characters
    for(var i in s) 
        if (+s[+i+1] == +s[i]+1 && 
            +s[+i+2] == +s[i]+2) return false;
    // Check for sequential alphabetical characters
    for(var i in s) 
        if (String.fromCharCode(s.charCodeAt(i)+1) == s[+i+1] && 
            String.fromCharCode(s.charCodeAt(i)+2) == s[+i+2]) return false;
    return true;
}

// For demo purposes only
var tests = [
    'efg123!$',
    'abcd567%',
    'xyz789^&',
    '#hijk23456',
    'ryiiu562@',
    'erty745#',
    'gjnfl45566^'
], sep = '\t\u2192 ', out = ['Fail','Pass'], eol = '<br>';
document.write('<pre>');
for(var i in tests) document.write(tests[i] + sep + out[+test(tests[i])] + eol);
document.write('</pre>');
qyswt5oh

qyswt5oh2#

这个包正是为了:https://github.com/zxcvbn-ts/zxcvbn
zxcvbn是受密码破解器启发的密码强度估计器。通过模式匹配和保守估计,它识别和加权40 k常见密码,常见的名字姓氏,维基百科上的流行词和不同国家不同语言中的常见词,以及其他常见模式,如日期,重复(aaa),序列(abcd),键盘模式(qwertyuiop)和l33 t speak。
考虑使用zxcvbn作为密码组合策略的算法替代方案-它更安全,更灵活,并且当网站需要最小复杂度分数来代替烦人的规则时,例如“密码必须包含{lower,upper,numbers,symbols}中的三个”。
更安全:策略通常在两个方面都失败,允许弱密码(P@ssword1),不允许强密码。更灵活:zxcvbn允许许多密码样式的繁荣,只要它检测到足够的复杂性-密码短语被评为高度给予足够的不常见的话,键盘模式是根据长度和圈数排名,大写字母增加了更多的复杂性时,它是不可预测的。更实用:zxcvbn的设计是为了支持简单、无规则的界面,给予即时反馈。除了强度估计之外,zxcvbn还包括最小的、有针对性的口头反馈,可以帮助引导用户使用不易猜测的密码。有关更多详细信息和动机,请参阅USENIX Security '16论文和演示文稿。
这个包还给出了如何加强密码的反馈,你可以设置一个所需的密码级别。
如果你自己编写正则表达式,你必须小心ReDoS,你可能也不会涵盖所有内容。..

g9icjywg

g9icjywg3#

通过循环字符并使用如下charCodeAt字符串方法,您可以获得类似于下面的函数。
注:这也是针对下面链接中提出的问题。
JavaScript中3个或更多连续字母数字字符的字符串验证

function validate() {
  var pwd = document.getElementById('password').value;
  var isValid = checkPassword(pwd);
  var elm = document.getElementById('result');
  elm.innerHTML = isValid ? 'Valid' : 'Invalid';
  elm.style.color = isValid ? 'green' : 'red';
}

function checkPassword(s) {
    
    if(s) {
       var test = (x) => !isNaN(x);
       var check = (x, y, i) => x + i === y;
    
       for(var i = 0; i < s.length - 2; i++) {
         if(test(s[i])) {
            if(test(s[i + 1]) && test(s[i + 2])) {
              if(check(Number(s[i]),Number(s[i + 1]), 1) &&
                check(Number(s[i]), Number(s[i + 2]), 2)) {
                return false;
              }
            }
         } else if(!test(s[i + 1]) && !test(s[i + 2])) {
            if(check(s.charCodeAt(i), s.charCodeAt(i + 1), 1) &&
                check(s.charCodeAt(i), s.charCodeAt(i + 2), 2)) {
                return false;
              }
         }
       }
      
    }
    
    return true;
}

document.getElementById('buttonToValidate').click();
<input type="text" id="password" value="efg123!$" /> 
<input type="button" id="buttonToValidate" value="Check" onclick="validate()" />
<span id="result" />
fv2wmkja

fv2wmkja4#

在上述答案的基础上增加降序检查;

function test(s) {
    // Check for sequential numerical characters
    for(var i in s){
      if (+s[+i+1] == +s[i]+1 ) return false;
      if (+s[+i+1]+1 == +s[i] ) return false;
    }

    // Check for sequential alphabetical characters
    for(var i in s){
      if (String.fromCharCode(s.charCodeAt(i)+1) == s[+i+1]) return false;
      if (String.fromCharCode(s.charCodeAt(i)-1) == s[+i+1]) return false;
    }

    return true;
  }

// For demo purposes only
var tests = [
    'efg123!$',
    'abcd567%',
    'xyz789^&',
    '#hijk23456',
    'ryiiu562@',
    'erty745#',
    'gjnfl45566^',
    '2a3b5c6',
    'mortz',
    '1357911'
], sep = '\t\u2192 ', out = ['Fail','Pass'], eol = '<br>';
document.write('<pre>');
for(var i in tests) document.write(tests[i] + sep + out[+test(tests[i])] + eol);
document.write('</pre>');
moiiocjp

moiiocjp5#

如果你想检查字符串中数字和字母的升序和降序,那么这里是一些其他建议的变体:

// Check for three or more sequential alphabetical characters asc/desc
function containsSequentialChars(chars) {
  const tests = [chars, chars.split('').reverse().join('')];

  for (let ii in tests) {
    const s = tests[ii];

    for (let i = 0; i < s.length; i++)
      if (
        String.fromCharCode(s.charCodeAt(i) + 1) === s[+i + 1] &&
        String.fromCharCode(s.charCodeAt(i) + 2) === s[+i + 2]
      )
        return true;
  }
  return false;
}

// Check for three or more sequential numerical characters asc/desc
function containsSequentialNums(chars) {
  const tests = [chars, chars.split('').reverse().join('')];

  for (let ii in tests) {
    const s = tests[ii];

    for (let i = 0; i < s.length; i++)
      if (+s[+i + 1] === +s[i] + 1 && +s[+i + 2] === +s[i] + 2) return true;
  }
  return false;
}

//UNIT TESTS
[
  { fixture: ['aBc', 'cBa', 'AbC', 'CbA'], expect: false },
  { fixture: ['abc', 'cba', 'ABC', 'CBA'], expect: true },
  { fixture: ['12', '21', '312', '1 2 3 4'], expect: false },
  { fixture: ['123', '1234', '321', '4321'], expect: true },
  { fixture: ['aaa123', 'aaa1234', 'aaa321', 'aaa4321'], expect: true },
].forEach((test) => {
  test.fixture.forEach((data) => {
    const result =
      containsSequentialChars(data) || containsSequentialNums(data);
    console.log(
      test.expect === result ? 'PASS\n' : 'FAIL\n',
      '\nexpected',
      test.expect,
      '\nactual',
      result,
      '\ndata: ',
      data
    );
  });
});

相关问题