본문 바로가기

Algorithm/Javascript로 코테 준비하기

[JS로 코테 준비하기] 14. 시저 암호 (feat. ASCII <-> 문자)

반응형

https://school.programmers.co.kr/learn/courses/30/lessons/12926

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

아스키코드와 문자 간의 변환 메서드에 대해 알아보자.

 

ASCII 코드표

가장 많이 쓰이는 영어 대소문자 부분의 아스키코드표이다.

영어 대소문자 <-> 아스키코드

 

Char to ASCII

  • charCodeAt()
  • 인자로 인덱스를 받아, 이에 대응하는 정수(아스키코드)를 반환한다.
const str = "abcdefg";

str.charCodeAt(); //97
str.charCodeAt(0); //97
str.charCodeAt(1); //98
str.charCodeAt(5); //102
str.charCodeAt(10); //NaN

 

 

ASCII to Char

  • String.fromCharCode()
  • 인자로 아스키코드를 받아, 이에 대응하는 문자열을 반환한다.
  • 여러 개의 숫자를 인자로 받을 수 있다.
String.fromCharCode(65) //'A'
String.fromCharCode(66) //'B'
String.fromCharCode(65, 66, 67) //'ABC'
String.fromCharCode(97) //'a'
String.fromCharCode(97, 102) //'af'

 

 

Unicode와 UTF-16

사실 위 메서드들은 UTF-16 코드 유닛을 기준으로 해당 코드와 문자 간 변환이 이루어진다. 간단한 설명을 위해 아스키코드라고 한 것이다. 이게 무슨 말인가 싶으니 조금 더 알아보자.

 

유니코드? UTF-16?

유니코드는 전 세계의 모든 문자를 표현한 방식이다. 모든 문자를 bit로 표현된 숫자(인덱스)로 매핑해 놓았고, 이 인덱스를 code point 혹은 code unit이라 부르기로 했다.

 

예를 들어, A라는 문자는 0x0041이라는 인덱스에 매핑되어 있다.

참고) 0x0041(16진수)는 65(10진수)이다.

 

그럼 UTF-16은 무엇인가? UTF(Unicode Transformation Format)는 유니코드 문자를 인코딩하는 방식이고, 그중 UTF-16은 하나의 인덱스를 16비트로 표현하는 방식이다.

 

인덱스라는 것이 위에서 불렀던 아스키코드라고 볼 수 있는 것이고, charCodeAtfromCharCode는 “UTF-16 방식을 기반으로 만든 인덱스"와 "문자(열)” 간 변환이 이루어지는 메서드인 것이다.

 

어째 메인 주제보다 길어지는 것 같은데.. 다음 메서드를 이해하기 위해서는 어쩔 수 없었다.

 

자바스크립트 아스키 변환에 대한 방법을 찾다 보면 위에서 정리한 메서드 외에 codePointAtfromCodePoint 가 종종 보인다. 근데 얘네가 무슨 차이가 있는지 잘 모르는 게 문제였다.

 

codePointAt()

charCodeAt()과 동작은 유사하지만,

const str = "abcdefg";

str.codePointAt(); //97
str.codePointAt(0); //97
str.codePointAt(1); //98
str.codePointAt(5); //102
str.codePointAt(10); //undefined

유니코드 기반이다. (더 넓은 범위의 문자 표현이 가능하다는 소리)

const icon = "🐎";

icon.charCodeAt(); //55357 -> icon이 표현하는 인덱스의 절반
icon.charCodeAt(1); //56334 -> icon이 표현하는 인덱스의 절반

icon.codePointAt(); //128014 -> icon이 표현하는 인덱스 전체

 

String.fromCodePoint()

fromCharCode()와 동작은 유사하지만,

String.fromCodePoint(65) //'A'
String.fromCodePoint(66) //'B'
String.fromCodePoint(65, 66, 67) //'ABC'

유니코드 기반이다. (더 넓은 범위의 문자 표현이 가능하다는 소리)

 

 

정리하자면

  • charCodeAtfromCharCode는 UTF-16 기반이고,
  • codePointAt과 fromCodePoint는 Unicode 기반이다.

 

 

소스 코드

음.. 좀 웃기지만 문제는 아스키를 사용하지 않았다. 아스키를 활용하지 않은 코드가 오히려 깔끔하다. 그저 처음에 아스키로 접근하면서, 찾아본 것을 정리하려고 가져왔다 😄

const UPPER_CASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const LOWER_CASE = "abcdefghijklmnopqrstuvwxyz";

function solution(s, n) {
    return [...s].map((c, i) => c === " " ? c :
        c.toUpperCase() === c ? UPPER_CASE[(UPPER_CASE.indexOf(c) + n) % 26] : LOWER_CASE[(LOWER_CASE.indexOf(c) + n) % 26]
    ).join('');
}

 

 

Reference

반응형