该程序是一个密码生成器,允许用户选择是否需要小写、大写、数字和特殊字符作为密码的一部分。每个选项都存储在其字符集的数组中。
我已经设法创建了程序,如果所有选项都为真,它将按预期运行。这些选项存储为confirm()
中的变量。然后,我将所有这些变量存储在一个对象中,以便于引用。
不幸的是,当任何条件为假时,我都无法执行程序。我无法计算出程序仍然执行的逻辑并忽略假条件,只提供变量中为真的选项。我认为我使用选项生成密码的逻辑是我出错的地方。除了使用多个if/else分支来评估每个可能的组合之外,我找不到以DRY方式做到这一点的方法。
// Function to prompt user for password options
function getPasswordOptions() {
var passwordLength;
do {
passwordLength = parseInt(prompt("How many characters would you like in your password (between 10 and 64)?"));
} while (passwordLength < 10 || passwordLength > 64);
// All the prompts for the type of password options that the user would like.
var lowercase = confirm("Would you like lowercase characters in your password?");
var uppercase = confirm("Would you like uppercase characters in your password?");
var special = confirm("Would you like special characters in your password?");
var numbers = confirm("Would you like numbers in your password?");
var userPasswordOpts = {
plength: passwordLength,
opt1: lowercase,
opt2: uppercase,
opt3: special,
opt4: numbers
};
return userPasswordOpts;
}
// Function for getting a random element from an array
function getRandom(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
// Function to generate password with user input
function generatePassword() {
var userPasswordChoice = getPasswordOptions();
var passwordArr = [];
if (Object.values(userPasswordChoice)) {
for (var i = 0; i < userPasswordChoice.plength; i++) {
var randomNum = Math.floor(Math.random() * 3) + 1;
switch(randomNum) {
case 1:
passwordArr.push(getRandom(lowerCasedCharacters));
break;
case 2:
passwordArr.push(getRandom(upperCasedCharacters));
break;
case 3:
passwordArr.push(getRandom(specialCharacters));
break;
case 4:
passwordArr.push(getRandom(numericCharacters));
default:
null;
}
}
}
return passwordArr.join('');
}
总是有更好的方法来编写算法,但我分享下面的代码给你一些想法。
function getRandom(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
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;
}
}
function generatePassword(passwordLength, userPasswordChoice) {
const passwordArr = [];
const charSets = {
lower: ['a','b','c'],
upper: ['A', 'B', 'C'],
special: ['@','#','!'],
numeric: [1,2,3],
}
if (Object.values(userPasswordChoice)) {
let chatSetArr = [];
const charSetTypes = Object.keys(userPasswordChoice).filter(charSetType => userPasswordChoice[charSetType]);
for (var i = 0; i < passwordLength/charSetTypes.length; i++) {
chatSetArr.push(...charSetTypes);
}
chatSetArr = chatSetArr.slice(chatSetArr.length-passwordLength);
shuffleArray(chatSetArr);
return chatSetArr.map(charSet => getRandom(charSets[charSet])).join('');
}
return '';
}
console.log(generatePassword(12,
{
lower: true,
upper: true,
special: true,
numeric: true,
}));
console.log(generatePassword(11,
{
lower: false,
upper: true,
special: true,
numeric: false,
}));
回答你的问题,(可能不是最好的"DRY";):
-
添加像trueCount这样的东西:注意,我还添加了一个optionsArr,其中包含您拥有的选项,并根据输入对所选选项进行过滤。
... var passwordArr = []; trueCount = Object.values(userPasswordChoice).filter(x => x==true).length; optionsArr = [lowerCasedCharacters, upperCasedCharacters, specialCharacters, numericCharacters]; chosenOptions = optionsArr.filter(x=> Object.values(userPasswordChoice)[optionsArr.indexOf(x)+1]); if (Object.values(userPasswordChoice)) { ...
-
取代了"3"by trueCount,因为这就是我们尝试
的次数 -
修改你的开关箱如下:
... var randomNum = Math.floor(Math.random() * trueCount) + 1; switch(randomNum) { case 1: passwordArr.push(getRandom(chosenOptions[0])); break; ...
PS,我很确定if条件:Object.values(userPasswordChoice)
它是一个数组,总是求值为true。