我正在尝试构建一个密码生成器,用于创建符合以下内容的密码:
- 最少8个字符,最多40个字符
- 必须至少包含1个大写,小写,数字和符号
醇>
我正在避免选择Math.random,我更喜欢加密选项。
我已经阅读了很多篇文章试图让它工作,但我遇到了以下问题:
输出字符串中似乎出现了随机空格,通常在最后。
- 醇>
输出值有时不符合min 8 char规则。
我意识到我可能有太多额外的if语句双重检查,但我很难看到它出错的地方。
这是进入另一个系统,所以我创建它尽可能模块化和功能。对于下面的大型片段道歉,我无法在jsfiddle.
function cryptoPassword(){
var minFieldNum = 8; //Minimum char size of desired output
var maxFieldNum = 40; //X defines their fields as 40 as the max_length
var outputValue = ''; //Output for field/overall function
var fieldRandom = getRandomInt(minFieldNum, maxFieldNum); //Generate length of password
if (fieldRandom < minFieldNum || fieldRandom > maxFieldNum) {
fieldRandom = getRandomInt(minFieldNum, maxFieldNum); //Regenerate if length doesn't conform - Not working?
}
else {
for (i = 0; outputValue.length < fieldRandom; i++) {
var mask = getRandomMask(); //Get mask selection
var randomChar = mask.charAt(getRandomInt(0,mask.length)); //Pick random char in mask
if (randomChar == " ") { //I don't know where the spaces come from
var randomChar = mask.charAt(getRandomInt(0,mask.length)); //Pick random char in mask
}
outputValue += randomChar; //Add to output
}
if (passwordChecker(outputValue, minFieldNum)) {
return outputValue + " " + passwordChecker(outputValue, minFieldNum);
}
else {
return cryptoPassword();
}
}
}
function getRandomInt(min, max) {
var byteArray = new Uint8Array(1);
window.crypto.getRandomValues(byteArray);
var range = (max - min + 1);
return min + (byteArray[0] % range);
}
function getRandomMask() {
var maskLcaseChar = 'abcdefghijklmnopqrstuvwxyz';
var maskUcaseChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var maskNumeric = '0123456789';
var maskSpecial = '!"$%^&*(){}[];#,./:@~<>?|_+-=';
var maskRandomNo = getRandomInt(0, 3);
var selectMask = [maskLcaseChar, maskUcaseChar, maskNumeric, maskSpecial];
return selectMask[maskRandomNo];
}
function passwordChecker(output, minSize){
var checkChars = '!"$%^&*(){}[];#,./:@~<>?|_+-=';
if (output.length < minSize){
return false
}
else if((output.toUpperCase() != output) && (output.toLowerCase() != output)) {
for (var i = 0; i < output.length; i++) {
if (checkChars.indexOf(output.charAt(i)) != -1) {
return true;
}
}
}
return false;
}
答案 0 :(得分:0)
所以问题似乎与getRandomInt函数有关,它会在0和掩码长度之间返回一个int。当你处理数组时,你真的希望它在0和数组-1的长度之间。
你正在从charAt函数返回空字符串,因为你要求在数组旁边放置一个位置。
我已经解决了这个问题并且还优化了生成部分。它总是从每个掩码中添加一个char,然后在其后随机获取它们。然后我将字符串洗牌,移动最初的4个。它不是使用加密来进行洗牌,但我不认为那是必要的。
function cryptoPassword(){
var maskLcaseChar = 'abcdefghijklmnopqrstuvwxyz';
var maskUcaseChar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var maskNumeric = '0123456789';
var maskSpecial = '!"$%^&*(){}[];#,./:@~<>?|_+-=';
var maskAll = maskLcaseChar + maskUcaseChar + maskNumeric + maskSpecial;
var mask = '';
var minFieldNum = 8; //Minimum char size of desired output
var maxFieldNum = 40; //X defines their fields as 40 as the max_length
var outputValue = ''; //Output for field/overall function
var fieldRandom = getRandomInt(minFieldNum, maxFieldNum); //Generate length of password
if (fieldRandom < minFieldNum || fieldRandom > maxFieldNum) {
console.log("error length", fieldRandom)
fieldRandom = getRandomInt(minFieldNum, maxFieldNum); //Regenerate if length doesn't conform - Not working?
}
else {
var randomChar = '';
var rnd;
randomChar = maskLcaseChar.charAt(getRandomInt(0,maskLcaseChar.length)); //Pick random lower case
outputValue += randomChar; //Add to output
randomChar = maskUcaseChar.charAt(getRandomInt(0,maskUcaseChar.length)); //Pick random upper case
outputValue += randomChar; //Add to output
randomChar = maskNumeric.charAt(getRandomInt(0,maskNumeric.length)); //Pick random numeric
outputValue += randomChar; //Add to output
randomChar = maskSpecial.charAt(getRandomInt(0,maskSpecial.length)); //Pick random special
outputValue += randomChar; //Add to output
mask = maskAll;
for (var i = 3; i < fieldRandom; i++) {
randomChar = mask.charAt(getRandomInt(0,mask.length)); //Pick random char
outputValue += randomChar;
}
outputValue = shuffleString(outputValue); //shuffle output
if (passwordChecker(outputValue, minFieldNum)) {
return outputValue + passwordChecker(outputValue, minFieldNum);
}
else {
console.log("error password", outputValue);
}
}
}
function shuffleString(inputString) {
var array = inputString.split('');
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.join('');
}
function getRandomInt(min, max) {
var byteArray = new Uint8Array(1);
window.crypto.getRandomValues(byteArray);
var range = (max - min);
var output = min + (byteArray[0] % range);
return output
}
function passwordChecker(output, minSize){
var checkChars = '!"$%^&*(){}[];#,./:@~<>?|_+-=';
if (output.length < minSize){
console.log("too short")
return false
}
else if((output.toUpperCase() != output) && (output.toLowerCase() != output)) {
for (var i = 0; i < output.length; i++) {
if (checkChars.indexOf(output.charAt(i)) != -1) {
if(output.indexOf(' ') === -1){
return true;
}
}
}
}
console.log("doesn't meet standards")
return false;
}
for(j=0; j<10000; j++){
cryptoPassword()
}
console.log("done")
我在底部添加了一个快速测试。它将生成10,000个密码。如果测试失败,它只会将它们输出到控制台。你可能想要删除它和一些console.log并稍微整理一下。