암호 생성기 만들기 문제

34922 단어
2020년 9월 27일

소개



이것은 내 자신의 기록을 위해 암호 생성기를 만들 때 직면했던 몇 가지 문제에 대한 간단한 게시물입니다. 암호 생성기를 만들지 않는 한 유용하지 않을 수 있습니다.

첫 번째 배열



먼저 암호 생성기가 선택할 문자 배열이 필요합니다. 다음과 같이 입력해 보겠습니다.

const alphabet = ['a','b','c','d','e','f']


...농담이구나. 우리는 지루함으로 죽을 것입니다. 배열에 6개의 문자를 얻기 위해 25자를 입력했습니다. 이것보다 더 좋은 방법이 있을 겁니다. 빠른 Google 검색을 통해 이 솔루션을 사용하여 StackOverflow.com으로 이동합니다.

alphabet = "abcdefghijklmnopqrstuvwxyz".split("");


작동하는지 확인하기 위해 console.log(alphabet)를 실행해 보겠습니다.

Array(26) [ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",  ] 


좋은 물건!

디버깅



생성된 암호가 사용자가 입력한 암호 길이와 일치하지 않는 경우가 있습니다. 다음은 사용자가 6자 길이의 암호를 요청했지만 암호 생성기가 3자 길이의 암호만 생성한 스크린샷입니다.



왜 그럴까요? 우리가 생명을 불어넣은 우리의 소중한 코드가 어찌하여 우리를 배반하고 등을 찌를 수 있겠습니까???

내가 이 버그를 단번에 찾아낸 천재였다고 할 수 있으면 좋겠지만 그렇지 않다. 나는 그 범위를 좁힐 수 있었고 사용자가 "특수 문자 포함"확인란을 선택한 경우에만 발생한다는 것을 발견했습니다.

그래서 필사적으로 특수 문자 배열에서 문자를 하나씩 제거하고 저장하고 몇 가지 암호를 생성하여 마법처럼 자체적으로 수정되었는지 확인하기 시작했습니다. 그리고 어느 순간 마법처럼 고쳐졌습니다. 그런 다음 저를 때렸습니다. '<' 및 '>' 문자.

output.innerHTML = hereIsYourPassword;


암호는 div를 사용하여 output라는 inner.HTML에 표시됩니다. 이는 암호에 해당 특수 문자가 포함된 경우 암호의 일부가 output 에 표시되지 않는 HTML 태그로 바뀌었음을 의미합니다. 신인 실수.

1억 개의 Else If 문 리팩토링



암호 생성기는 4개의 확인란으로 끝났습니다. 하나는 소문자용, 하나는 대문자용, 하나는 숫자용, 하나는 특수문자용입니다. 그 결과 체크할 수 있는 모든 확인란 조합을 포함하는 약 1억 개else if statements가 되었습니다. 아래에 표시:

function chooseFunction() {
  if (
    includeLowerCase.checked === false &&
    includeSymbols.checked === false &&
    includeNumbers.checked === false &&
    includeUpperCase.checked === false
  ) {
    checkPasswordInput();
  } else if (
    includeLowerCase.checked === true &&
    includeSymbols.checked === false &&
    includeNumbers.checked === false &&
    includeUpperCase.checked === false
  ) {
    checkPasswordInput();
    generateBasicPassword();
  } else if (
    includeLowerCase.checked === true &&
    includeSymbols.checked === true &&
    includeNumbers.checked === false &&
    includeUpperCase.checked === false
  ) {
    checkPasswordInput();
    generateBasicPasswordWithSpecialSymbols();
  } else if (
    includeLowerCase.checked === true &&
    includeSymbols.checked === false &&
    includeNumbers.checked === true &&
    includeUpperCase.checked === false
  ) {
    checkPasswordInput();
    generateBasicPasswordWithNumbers();
  } else if (
    includeLowerCase.checked === true &&
    includeSymbols.checked === false &&
    includeNumbers.checked === false &&
    includeUpperCase.checked === true
  ) {
    checkPasswordInput();
    generateBasicPasswordWithUpperCase();
  } else if (
    includeLowerCase.checked === true &&
    includeSymbols.checked === true &&
    includeNumbers.checked === true &&
    includeUpperCase.checked === false
  ) {
    checkPasswordInput();
    generateBasicPasswordWithSpecialSymbolsAndNumbers();
  } else if (
    includeLowerCase.checked === true &&
    includeSymbols.checked === true &&
    includeNumbers.checked === false &&
    includeUpperCase.checked === true
  ) {
    checkPasswordInput();
    generateBasicPasswordWithSpecialSymbolsAndUpperCase();
  } else if (
    includeLowerCase.checked === true &&
    includeSymbols.checked === false &&
    includeNumbers.checked === true &&
    includeUpperCase.checked === true
  ) {
    checkPasswordInput();
    generateBasicPasswordWithNumbersAndUpperCase();
  } else if (
    includeLowerCase.checked === true &&
    includeSymbols.checked === true &&
    includeNumbers.checked === true &&
    includeUpperCase.checked === true
  ) {
    checkPasswordInput();
    generateBasicPasswordWithAllOptions();
  } else if (
    includeLowerCase.checked === false &&
    includeSymbols.checked === true &&
    includeNumbers.checked === false &&
    includeUpperCase.checked === false
  ) {
    checkPasswordInput();
    generateSpecialCharactersOnly();
  } else if (
    includeLowerCase.checked === false &&
    includeSymbols.checked === false &&
    includeNumbers.checked === true &&
    includeUpperCase.checked === false
  ) {
    checkPasswordInput();
    generateNumbersOnly();
  } else if (
    includeLowerCase.checked === false &&
    includeSymbols.checked === false &&
    includeNumbers.checked === false &&
    includeUpperCase.checked === true
  ) {
    checkPasswordInput();
    generateUpperCaseOnly();
  } else if (
    includeLowerCase.checked === false &&
    includeSymbols.checked === true &&
    includeNumbers.checked === true &&
    includeUpperCase.checked === false
  ) {
    checkPasswordInput();
    generateSpecialSymbolsWithNumbers();
  } else if (
    includeLowerCase.checked === false &&
    includeSymbols.checked === true &&
    includeNumbers.checked === false &&
    includeUpperCase.checked === true
  ) {
    checkPasswordInput();
    generateSpecialSymbolsWithUpperCase();
  } else if (
    includeLowerCase.checked === false &&
    includeSymbols.checked === true &&
    includeNumbers.checked === true &&
    includeUpperCase.checked === true
  ) {
    checkPasswordInput();
    generateSymbolsPasswordWithNumbersAndUpperCase();
  } else if (
    includeLowerCase.checked === false &&
    includeSymbols.checked === false &&
    includeNumbers.checked === true &&
    includeUpperCase.checked === true
  ) {
    checkPasswordInput();
    generateNumbersPasswordWithUpperCase();
  }
}


내 안의 야심찬 개발자는 “야! 나는 이것이 좋은 코드 맨으로 간주되지 않는다고 생각합니다. 자신이 무엇을 하고 있는지 실제로 아는 사람에게 도움을 요청해야 할까요?”

그래서 Commit Your Code라는 DThompsonDev의 Discord 채널에서 도움을 요청했습니다. 응답은 4if statements를 사용하고 필요에 따라 배열을 연결하는 것이었습니다. 이것은 위의 1억else if statements을 다음과 같이 변경했습니다.

function generateAllPasswords() {
  let finalArray = [];

  if (includeLowerCase.checked === true) {
    finalArray = finalArray.concat(alphabetLowerCase);
  }

  if (includeSymbols.checked === true) {
    finalArray = finalArray.concat(specialCharacters);
  }

  if (includeNumbers.checked === true) {
    finalArray = finalArray.concat(numbers);
  }

  if (includeUpperCase.checked === true) {
    finalArray = finalArray.concat(alphabetUpperCase);
  }

  checkPasswordInput();
  getCharacters(finalArray);
}


여러 개if statements가 차례로 그런 식으로 사용되는 것을 본 적이 없습니다. 1개if statement 또는 다수else if statements만 본 적이 있습니다. 이 리팩토링은 또한 체크박스의 각 조합에 대해 선언했던 모든 개별 기능을 제거하고 단일 기능으로 줄일 수 있음을 의미했습니다. 전체 결과는 JavaScript의 605줄에서 158줄로 줄었습니다.

결론



필요할 때 도움을 요청하십시오. 확인란의 모든 조합을 거치는 데는 시간이 많이 걸렸습니다. 그런 다음 다른 사람이 몇 분 동안 코드를 보고 "이렇게 해보세요."라고 말했습니다.

암호 생성기를 만든 지 2주가 지났기 때문에 기억할 수 있는 모든 문제에 관한 것입니다. 안녕.

좋은 웹페이지 즐겨찾기