Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript 문자열 암호화: 알파벳 시프트 방식의 시저 암호 구현하기

문제 정의

첫 번째 인수로 문자열을, 두 번째 인수로 숫자를 받는 JavaScript 함수를 작성해야 합니다.

이 함수는 문자열에 포함된 각 알파벳을 주어진 숫자만큼 알파벳 순서상 뒤로 밀어 새로운 문자로 치환해야 합니다.

여기서 중요한 조건은 이동 결과가 알파벳 범위를 벗어날 때 다시 처음이나 끝으로 순환(wrap around)되어야 한다는 점입니다. 예를 들어 z 다음에는 undefined 같은 빈 값이 아니라 a가 이어져야 하며, 반대로 a보다 앞으로 밀어야 할 때는 z로 연결됩니다. 이 방식은 고전 암호학에서 널리 알려진 시저 암호(Caesar Cipher)와 정확히 같은 원리입니다.

예제 코드

다음은 위 요구 사항을 만족하는 전체 코드입니다.

const str = 'this is a str';
const encryptString = (str = '', num = 1) => {
    const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
    str = str.toLowerCase();
    let res = '';
    for (let i = 0; i < str.length; i++) {
        const letter = str[i];
        // 알파벳이 아닌 문자(공백, 숫자, 기호 등)는 그대로 유지
        if (alphabet.indexOf(letter) === -1) {
            res += letter;
            continue;
        }
        let index = alphabet.indexOf(letter) + num % 26;
        if (index > 25) {
            index -= 26;
        }
        if (index < 0) {
            index += 26;
        }
        if (str[i] === str[i].toUpperCase()) {
            res += alphabet[index].toUpperCase();
        } else {
            res += alphabet[index];
        }
    }
    return res;
};
console.log(encryptString(str, 4));

출력 결과

콘솔에 출력되는 결과는 다음과 같습니다.

xlmw mw e wxv

'this is a str'의 각 알파벳이 4칸씩 뒤로 밀려 'xlmw mw e wxv'로 바뀐 것을 확인할 수 있습니다. (t→x, h→l, i→m, s→w)

코드 동작 원리

함수가 어떻게 동작하는지 단계별로 살펴보겠습니다.

  1. 알파벳 기준 배열 생성: 소문자 a부터 z까지의 문자열을 split('')으로 한 글자씩 나눠 배열로 만듭니다. 이 배열의 인덱스를 기준으로 글자를 치환합니다.
  2. 소문자 통일: 입력 문자열을 toLowerCase()로 모두 소문자로 변환해 인덱스 계산을 단순하게 만듭니다.
  3. 알파벳 외 문자 처리: 공백이나 특수문자처럼 알파벳 배열에 없는 문자는 indexOf()의 결과가 -1이므로 그대로 결과에 추가한 뒤 건너뜁니다.
  4. 순환(랩어라운드) 처리: 현재 인덱스에 이동량(num % 26)을 더한 값이 25를 초과하면 26을 빼고, 음수가 되면 26을 더해 항상 0~25 범위 안에 머물도록 합니다. 덕분에 z에서 a로, a에서 z로 자연스럽게 순환하며, 음수 이동(복호화)도 가능합니다.
  5. 결과 조합: 치환된 글자들을 하나의 문자열로 이어 붙여 최종 결과로 반환합니다.

참고: 대소문자 유지

위 코드는 처리 전에 문자열 전체를 소문자로 변환하기 때문에 출력은 항상 소문자로 반환됩니다. 입력의 대소문자를 그대로 유지하고 싶다면 각 글자의 원래 대소문자 여부를 변환 전에 저장해 두었다가 결과에 반영하면 됩니다.