使用javascript中的要求生成随机密码字符串

时间:2012-03-15 12:21:02

标签: javascript

我想生成一个随机字符串,该字符串必须包含来自a-z和3个数字的5个字母。

如何使用javascript执行此操作?

我有以下脚本,但它不符合我的要求。

        var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
        var string_length = 8;
        var randomstring = '';
        for (var i=0; i<string_length; i++) {
            var rnum = Math.floor(Math.random() * chars.length);
            randomstring += chars.substring(rnum,rnum+1);
        }

23 个答案:

答案 0 :(得分:266)

强制使用固定数量的字符是错误的想法。它不会提高密码的质量。更糟糕的是,它减少了可能的密码数量,因此通过强制攻击变得更容易。

要生成由字母数字字符组成的随机单词,请使用:

var randomstring = Math.random().toString(36).slice(-8);

它是如何运作的?

Math.random()                        // Generate random number, eg: 0.123456
             .toString(36)           // Convert  to base-36 : "0.4fzyo82mvyr"
                          .slice(-8);// Cut off last 8 characters : "yo82mvyr"

Number.prototype.toStringstring.prototype.slice方法的文档。

答案 1 :(得分:35)

更加可维护和安全的方法。

&#13;
&#13;
var Password = {
 
  _pattern : /[a-zA-Z0-9_\-\+\.]/,
  
  
  _getRandomByte : function()
  {
    // http://caniuse.com/#feat=getrandomvalues
    if(window.crypto && window.crypto.getRandomValues) 
    {
      var result = new Uint8Array(1);
      window.crypto.getRandomValues(result);
      return result[0];
    }
    else if(window.msCrypto && window.msCrypto.getRandomValues) 
    {
      var result = new Uint8Array(1);
      window.msCrypto.getRandomValues(result);
      return result[0];
    }
    else
    {
      return Math.floor(Math.random() * 256);
    }
  },
  
  generate : function(length)
  {
    return Array.apply(null, {'length': length})
      .map(function()
      {
        var result;
        while(true) 
        {
          result = String.fromCharCode(this._getRandomByte());
          if(this._pattern.test(result))
          {
            return result;
          }
        }        
      }, this)
      .join('');  
  }    
    
};
&#13;
<input type='text' id='p'/><br/>
<input type='button' value ='generate' onclick='document.getElementById("p").value = Password.generate(16)'>
&#13;
&#13;
&#13;

答案 2 :(得分:14)

许多答案(包括本答案的原文)都没有解决OP的字母和数字计数要求。以下是两种解决方案:一般(无最小字母/数字)和规则。

一般:

我认为这是比上述更好的通用解决方案,因为:

  • 它比接受/最高投票的答案更安全,也更通用,因为它支持以区分大小写的方式设置任何字符集
  • 它比其他答案更简洁(一般解决方案,最多3行;可以是单行)
  • 它仅使用原生Javascript-无需安装或其他需要的库

请注意

  • 为了在IE上工作,Array.fill()原型必须是polyfilled
  • 如果可用,最好使用window.crypto.getRandomValues()而不是Math.random()(感谢@BenjaminH指出)

三衬垫:

var pwdChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var pwdLen = 10;
var randPassword = Array(pwdLen).fill(pwdChars).map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');

或者,作为一线:

var randPassword = Array(10).fill("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz").map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('');

使用字母/数字规则

现在,上面的一个变种。这将从给定的字符集生成三个随机字符串(字母,数字,或者),然后对结果进行加扰。

请注意,以下使用sort()仅用于说明目的。对于生产用途,请使用shuffleDurstenfeld函数替换下面的sort()函数。

首先,作为一个功能:

function randPassword(letters, numbers, either) {
  var chars = [
   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", // letters
   "0123456789", // numbers
   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" // either
  ];

  return [letters, numbers, either].map(function(len, i) {
    return Array(len).fill(chars[i]).map(function(x) {
      return x[Math.floor(Math.random() * x.length)];
    }).join('');
  }).concat().join('').split('').sort(function(){
    return 0.5-Math.random();
  }).join('')
}

// invoke like so: randPassword(5,3,2);

同样的事情,作为一个2轮胎(诚然,非常长而丑陋的线条 - 如果你使用适当的随机播放功能,它将不会成为1-liner。不推荐但有时它很有趣无论如何):

var chars = ["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz","0123456789", "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"];
var randPwd = [5,3,2].map(function(len, i) { return Array(len).fill(chars[i]).map(function(x) { return x[Math.floor(Math.random() * x.length)] }).join('') }).concat().join('').split('').sort(function(){return 0.5-Math.random()}).join('');

答案 3 :(得分:8)

这不是完全优化的,但应该有效。

var chars = "ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
var string_length = 8;
var randomstring = '';
var charCount = 0;
var numCount = 0;

for (var i=0; i<string_length; i++) {
    // If random bit is 0, there are less than 3 digits already saved, and there are not already 5 characters saved, generate a numeric value. 
    if((Math.floor(Math.random() * 2) == 0) && numCount < 3 || charCount >= 5) {
        var rnum = Math.floor(Math.random() * 10);
        randomstring += rnum;
        numCount += 1;
    } else {
        // If any of the above criteria fail, go ahead and generate an alpha character from the chars string
        var rnum = Math.floor(Math.random() * chars.length);
        randomstring += chars.substring(rnum,rnum+1);
        charCount += 1;
    }
}

alert(randomstring);

这是一个供你测试的jsfiddle:http://jsfiddle.net/sJGW4/3/

答案 4 :(得分:6)

我写了一篇小答案,灵感来自你的回答:

(function(){g=function(){c='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';p='';for(i=0;i<8;i++){p+=c.charAt(Math.floor(Math.random()*62));}return p;};p=g();while(!/[A-Z]/.test(p)||!/[0-9]/.test(p)||!/[a-z]/.test(p)){p=g();}return p;})()

此函数返回密码,可用于以下书签:

javascript:alert(TheCodeOfTheFunction);

答案 5 :(得分:5)

适用于正在寻找最简单脚本的人。没有while (true),没有if/else,没有声明。

基于mwag的答案,但是这个使用crypto.getRandomValues,比Math.random的随机性强。

Array(20)
  .fill('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$')
  .map(x => x[Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * (x.length + 1))])
  .join('');

有关0xffffffff的神奇之处,请参见this


打开控制台并进行自我测试:

for (let i = 0 ; i < 100; i++)
  console.log(
    Array(20)
    .fill('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$')
    .map(x => x[Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * (x.length + 1))])
    .join('')
  )

如果考虑性能,可以尝试以下方法:

var generate = (
  length = 20,
  wishlist = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!@-#$"
) => Array(length)
      .fill('') // fill an empty will reduce memory usage
      .map(() => wishlist[Math.floor(crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * (wishlist.length + 1))])
      .join('');

// Generate 100 passwords
for (var i = 0; i < 100; i++) console.log(generate());

答案 6 :(得分:5)

如果您需要使用至少1个数字,1个大写字符和1个小写字符生成密码:

function generatePassword(passwordLength) {
  var numberChars = "0123456789";
  var upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  var lowerChars = "abcdefghijklmnopqrstuvwxyz";
  var allChars = numberChars + upperChars + lowerChars;
  var randPasswordArray = Array(passwordLength);
  randPasswordArray[0] = numberChars;
  randPasswordArray[1] = upperChars;
  randPasswordArray[2] = lowerChars;
  randPasswordArray = randPasswordArray.fill(allChars, 3);
  return shuffleArray(randPasswordArray.map(function(x) { return x[Math.floor(Math.random() * x.length)] })).join('');
}

function shuffleArray(array) {
  for (var i = array.length - 1; i > 0; i--) {
    var j = Math.floor(Math.random() * (i + 1));
    var temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
  return array;
}

alert(generatePassword(12));

如果你想玩/测试,这里是小提琴:http://jsfiddle.net/sJGW4/155/

支持@mwag让我开始创建它。

答案 7 :(得分:4)

好吧,如果我能很好地理解您正在尝试获取一个随机字符串密码,该密码包含5个字母和3个随机放置的密码,因此长度为8个字符并且可以接受大写和小写字母,则可以使用以下功能:

function randPass(lettersLength,numbersLength) {
    var j, x, i;
    var result           = '';
    var letters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    var numbers       = '0123456789';
    for (i = 0; i < lettersLength; i++ ) {
        result += letters.charAt(Math.floor(Math.random() * letters.length));
    }
    for (i = 0; i < numbersLength; i++ ) {
        result += numbers.charAt(Math.floor(Math.random() * numbers.length));
    }
    result = result.split("");
    for (i = result.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = result[i];
        result[i] = result[j];
        result[j] = x;
    }
    result = result.join("");
    return result
}

function randPass(lettersLength,numbersLength) {
    var j, x, i;
    var result           = '';
    var letters       = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
    var numbers       = '0123456789';
    for (i = 0; i < lettersLength; i++ ) {
        result += letters.charAt(Math.floor(Math.random() * letters.length));
    }
    for (i = 0; i < numbersLength; i++ ) {
        result += numbers.charAt(Math.floor(Math.random() * numbers.length));
    }
    result = result.split("");
    for (i = result.length - 1; i > 0; i--) {
        j = Math.floor(Math.random() * (i + 1));
        x = result[i];
        result[i] = result[j];
        result[j] = x;
    }
    result = result.join("");
    return result
}
console.log(randPass(5,3))

答案 8 :(得分:3)

正如@RobW所说,将OP密码限制为OP方案中提出的固定数量的字符是一个坏主意。但更糟糕的是,建议基于Math.random的代码的答案是 非常糟糕的主意

让我们从坏主意开始。 OP代码从一组62中随机选择一个8个字符的字符串。将随机字符串限制为5个字母和3个数字意味着生成的密码最多 ,28.5位熵(相反,如果删除了5个字母和3个数字的分布限制,则为47.6位的电位)。那不是很好。但实际上情况更糟。通过使用Math.random作为生成密码熵的方法,销毁了代码的 最佳 方面。 Math.random伪随机数生成器。由于伪随机数生成器的确定性,生成的密码的熵非常糟糕,使任何此类提议的解决方案 非常糟糕 。假设这些密码被发送给最终用户(不管是什么意思),接收这样一个密码的活跃对手很有可能预测将来的密码发送给其他用户,这可能不是一件好事。 / p>

但回到刚刚坏主意。假设使用加密强伪随机数生成器而不是Math.random。为什么要将密码限制为28.5位?如上所述,这不是很好。据推测,5个字母,3个数字方案是帮助用户管理随机发出的密码。但是让我们面对它,你必须平衡易用性使用价值,并且28.5位熵对防御活跃对手没有多大价值。

但足够糟糕。让我们提出一条前进的道路。我将使用JavaScript EntropyString库“有效地从各种字符集生成加密强大的随机字符串指定熵”。我将使用一个包含32个字符的字符集,而不是OP 62字符,以减少使用容易混淆的字符或形成英文单词。而不是5个字母,3个数字方案(熵太少),我宣称密码将有60位熵(这是缓和与价值的平衡)。

import {Random, charSet32} from 'entropy-string'
const random = new Random(charSet32)
const string = random.string(60)
  

“Q7LfR8Jn7RDp”

注意random.string的参数是所需的熵位,而不是更常见的随机字符串生成解决方案,它指定传入字符串长度(这是误导的,通常是未指定的,但这是另一个故事)

答案 9 :(得分:2)

我不建议使用强制密码,因为它限制了用户的安全性,但无论如何,有几种方法可以实现 -

传统的JavaScript方法 -

Math.random().toString(36).slice(-8);

使用随机字符串

安装随机字符串:

npm install randomstring

在App.js中使用它 -

var randStr = require('randomstring');

var yourString = randStr.generate(8);

您的密码值保存在变量yourString

不要使用强制密码!

强制密码可能会损害您的安全性,因为所有密码都在同一个字符集下,这可能很容易被破坏!

答案 10 :(得分:2)

var letters = ['a','b','c','d','e','f','g','h','i','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
    var numbers = [0,1,2,3,4,5,6,7,8,9];
    var randomstring = '';

        for(var i=0;i<5;i++){
            var rlet = Math.floor(Math.random()*letters.length);
            randomstring += letters[rlet];
        }
        for(var i=0;i<3;i++){
            var rnum = Math.floor(Math.random()*numbers.length);
            randomstring += numbers[rnum];
        }
     alert(randomstring);

答案 11 :(得分:1)

最后,不使用浮点黑客:

function genpasswd(n) {
    // 36 ** 11 > Number.MAX_SAFE_INTEGER
    if (n > 10)
        throw new Error('Too big n for this function');
    var x = "0000000000" + Math.floor(Number.MAX_SAFE_INTEGER * Math.random()).toString(36);
    return x.slice(-n);
}

答案 12 :(得分:1)

基于我的加密货币的问题。使用ES6并省略所有浏览器功能检查。对安全性或性能有何评论?

const generatePassword = (
  passwordLength = 12,
  passwordChars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
) =>
  [...window.crypto.getRandomValues(new Uint32Array(passwordLength))]
    .map(x => passwordChars[x % passwordChars.length])
    .join('');

答案 13 :(得分:1)

创建名为PassswordGeneratorService的密码生成器服务

import { Injectable } from '@angular/core';

@Injectable()
export class PasswordGeneratorService {

  generatePassword(length:number,upper:boolean,numbers:boolean,symbols:boolean) {
    const passwordLength = length || 12;
    const addUpper =  upper;
    const addNumbers =  numbers;
    const addSymbols =  symbols;

    const lowerCharacters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
    const upperCharacters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
    const numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
    const symbols = ['!', '?', '@'];

    const getRandom = array => array[Math.floor(Math.random() * array.length)];

    let finalCharacters = '';

    if (addUpper) {
      finalCharacters = finalCharacters.concat(getRandom(upperCharacters));
    }

    if (addNumbers) {
      finalCharacters = finalCharacters.concat(getRandom(numbers));
    }

    if (addSymbols) {
      finalCharacters = finalCharacters.concat(getRandom(symbols));
    }

    for (let i = 1; i < passwordLength - 3; i++) {
      finalCharacters = finalCharacters.concat(getRandom(lowerCharacters));
    }

    return  finalCharacters.split('').sort(() => 0.5 - Math.random()).join('');
  }
}

不要忘记在您使用的模块上添加服务

@NgModule({
  imports: [
    CommonModule,
    SharedModule,
    CommonModule,
    RouterModule.forChild(routes),
    FormsModule,
    ReactiveFormsModule,
    FlexLayoutModule,
    TranslateModule,
    ExistingUserDialogModule,
    UserDocumentsUploadDialogModule
  ],
  declarations: [
    UserListComponent,
    EditUserDialogComponent,
    UserEditorComponent
  ],
  entryComponents: [
    EditUserDialogComponent
  ],
  providers: [
    AuthService,
    PasswordGeneratorService
  ]
})
export class UsersModule {
}

在您的控制器上添加一个方法,该方法在服务内部调用generate password方法并在密码字段上设置结果

  constructor(
     private passwordGenerator: PasswordGeneratorService,
    )
  get newPassword() {
    return this.password.get('newPassword');
  }
  generatePassword() {
    this.newPassword.setValue(this.passwordGenerator.generatePassword(8,true,true,true));
  }

答案 14 :(得分:1)

使用Math.random()生成的任何密码都是极端错误

此功能使用系统时间作为随机数生成器的种子。任何知道密码生成时间的人都可以轻松地对密码进行暴力破解。

在几乎所有情况下,此数据都很容易获得-只需将其输入到被黑数据库中的registration_time列,并使用15分钟至0分钟之前的时间测试Math.random()算法生成的所有值。 / p>

用Math.random()生成的密码是完全没用的,因为首次使用该密码的时间足以破解它。

答案 15 :(得分:1)

这是一种创建灵活生成器的方法,允许您添加一些规则:

function generatePassword(length, rules) {
    if (!length || length == undefined) {
        length = 8;
    }

    if (!rules || rules == undefined) {
        rules = [
            {chars: "abcdefghijklmnopqrstuvwxyz", min: 3},  // As least 3 lowercase letters
            {chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", min: 2},  // At least 2 uppercase letters
            {chars: "0123456789", min: 2},                  // At least 2 digits
            {chars: "!@#$&*?|%+-_./:;=()[]{}", min: 1}      // At least 1 special char
        ];
    }

    var allChars = "", allMin = 0;
    rules.forEach(function(rule) {
        allChars += rule.chars;
        allMin += rule.min;
    });
    if (length < allMin) {
        length = allMin;
    }
    rules.push({chars: allChars, min: length - allMin});
    
    var pswd = "";
    rules.forEach(function(rule) {
        if (rule.min > 0) {
            pswd += shuffleString(rule.chars, rule.min);
        }
    });
    
    return shuffleString(pswd);
}

function shuffleString(str, maxlength) {
    var shuffledString = str.split('').sort(function(){return 0.5-Math.random()}).join('');
    if (maxlength > 0) {
        shuffledString = shuffledString.substr(0, maxlength);
    }
    return shuffledString;
}

var pswd = generatePassword(15, [
  {chars: "abcdefghijklmnopqrstuvwxyz", min: 4},  // As least 4 lowercase letters
  {chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", min: 1},  // At least 1 uppercase letters
  {chars: "0123456789", min: 3},                  // At least 3 digits
  {chars: "!@#$&*?|%+-_./:;=()[]{}", min: 2}      // At least 2 special chars
]);

console.log(pswd, pswd.length);

答案 16 :(得分:1)

根据上面@Ryan Shillington 的回答,您可能会发现此增强功能也很有帮助。 认为这比上述问题中原始请求所请求的更安全。

  1. 生成的密码至少包含 1 个数字、1 个大写字符、1 个小写字符和 1 个特殊字符
  2. 密码长度是动态的

//Password generated with at least 1 number, 1 upper case character, 1 lower case character and 1 Special character
function generatePassword() 
{
      var passwordLength = randomIntFromInterval(10,20);    
      var numberChars = "0123456789";
      var upperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      var lowerChars = "abcdefghijklmnopqrstuvwxyz";
      var specialChars = "~!#$%&*-+|";
      var allChars = numberChars + upperChars + lowerChars + specialChars;
      var randPasswordArray = Array(passwordLength);
      randPasswordArray[0] = numberChars;
      randPasswordArray[1] = upperChars;
      randPasswordArray[2] = lowerChars;
      randPasswordArray[3] = specialChars;
      randPasswordArray = randPasswordArray.fill(allChars, 4);
      if(window.crypto && window.crypto.getRandomValues)
      {
          return shuffleArray(randPasswordArray.map(function(x) { return x[Math.floor(window.crypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * x.length)] })).join('');  
      }
      else if(window.msCrypto && window.msCrypto.getRandomValues) 
      {
          return shuffleArray(randPasswordArray.map(function(x) { return x[Math.floor(window.msCrypto.getRandomValues(new Uint32Array(1))[0] / (0xffffffff + 1) * x.length)] })).join('');
      }else{
          return shuffleArray(randPasswordArray.map(function(x) { return x[Math.floor(Math.random() * x.length)] })).join('');
      }
      
    }

    function shuffleArray(array) 
    {
      for (var i = array.length - 1; i > 0; i--) {
        var j = Math.floor(Math.random() * (i + 1));
        var temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
     
     return array;
}

//generate random number in the range (min and max included)
function randomIntFromInterval(min, max) {
      return Math.floor(Math.random() * (max - min + 1) + min);
}
<input type='text' id='p9'/>
<input type='button' value ='pass generator' onclick='document.getElementById("p9").value = generatePassword()'>

答案 17 :(得分:0)

有一个选定长度的随机密码字符串生成器

&#13;
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.11/angular.min.js"></script>
<div ng-app="app" ng-controller="appCtrl">
  <my-component format="format"></my-component>
  <my-component format="'(tz, offset) location, year'"></my-component>
</div>
&#13;
let input = document.querySelector("textarea");
let button = document.querySelector("button");
let length = document.querySelector("input");

function generatePassword(n) 
{
	let pwd = "";

  while(!pwd || pwd.length < n)
  {
  	pwd += Math.random().toString(36).slice(-22);
  }
  
  return pwd.substring(0, n);
}

button.addEventListener("click", function()
{
	input.value = generatePassword(length.value);
});
&#13;
&#13;
&#13;

答案 18 :(得分:0)

使用1个大写字符保护密码。

template <class T>
class ThreadWrapper
{
public:
    ThreadWrapper(std::function<void(T *object)> function, T *object) :
    {
        m_thread = std::thread(WrapFunction, function, object);
        //optionally
        m_thread.detach();
    }
    static void WrapFunction(ThreadWrapper *wrapper, std::function<void()> function, T *object)
    {
        // Get the thread id and save in the object
        object->SetThreadId(get_id());
        // Now actually invoke the thread routine, with the id already installed.
        function(object);
    }
}

// Cleanup is left as an exercise for the reader.

答案 19 :(得分:0)

尝试一下,就可以了。 将脚本下载到您的javascript应用程序并调用函数 randomPassword() https://gist.github.com/enishant/4ba920c71f338e83c7089dc5d6f33a64

答案 20 :(得分:0)

好吧,您始终可以使用最新版本浏览器中可用的window.crypto对象。

只需要一行代码即可获得一个随机数:

let n = window.crypto.getRandomValues(new Uint32Array(1))[0];

它也有助于加密和解密数据。 有关更多信息,请访问MDN Web docs - window.crypto

答案 21 :(得分:0)

var Password = {
 
  _pattern : /[a-zA-Z0-9_\-\+\.]/,
  
  
  _getRandomByte : function()
  {
    // http://caniuse.com/#feat=getrandomvalues
    if(window.crypto && window.crypto.getRandomValues) 
    {
      var result = new Uint8Array(1);
      window.crypto.getRandomValues(result);
      return result[0];
    }
    else if(window.msCrypto && window.msCrypto.getRandomValues) 
    {
      var result = new Uint8Array(1);
      window.msCrypto.getRandomValues(result);
      return result[0];
    }
    else
    {
      return Math.floor(Math.random() * 256);
    }
  },
  
  generate : function(length)
  {
    return Array.apply(null, {'length': length})
      .map(function()
      {
        var result;
        while(true) 
        {
          result = String.fromCharCode(this._getRandomByte());
          if(this._pattern.test(result))
          {
            return result;
          }
        }        
      }, this)
      .join('');  
  }    
    
};
<input type='text' id='p'/><br/>
<input type='button' value ='generate' onclick='document.getElementById("p").value = Password.generate(16)'>

答案 22 :(得分:0)

生成一个长度为 8 到 32 个字符的随机密码,其中至少有 1 个小写字母、1 个大写字母、1 个数字、1 个 spl 字符 (!@$&)

    function getRandomUpperCase() {
       return String.fromCharCode( Math.floor( Math.random() * 26 ) + 65 );
    }
    
    function getRandomLowerCase() {
       return String.fromCharCode( Math.floor( Math.random() * 26 ) + 97 );
    } 
    
    function getRandomNumber() {
       return String.fromCharCode( Math.floor( Math.random() * 10 ) + 48 );
    }
    
    function getRandomSymbol() {
        // const symbol = '!@#$%^&*(){}[]=<>/,.|~?';
        const symbol = '!@$&';
        return symbol[ Math.floor( Math.random() * symbol.length ) ];
    }
    
    const randomFunc = [ getRandomUpperCase, getRandomLowerCase, getRandomNumber, getRandomSymbol ];
    
    function getRandomFunc() {
        return randomFunc[Math.floor( Math.random() * Object.keys(randomFunc).length)];
    }
    
    function generatePassword() {
        let password = '';
        const passwordLength = Math.random() * (32 - 8) + 8;
        for( let i = 1; i <= passwordLength; i++ ) {
            password += getRandomFunc()();
        }
        //check with regex
        const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,32}$/
        if( !password.match(regex) ) {
            password = generatePassword();
        }
        return password;
    }
    
    console.log( generatePassword() );