JavaScript / fromCharCode()로 UTF-16 코드 값을 문자로 변환하기
String.fromCharCode()는 숫자로 지정한 UTF-16 코드 단위를 이어 문자열을 만드는 정적 메서드입니다. 문자열에서 코드 단위 숫자를 읽는 charCodeAt()과 방향이 반대입니다. 일부 이모지처럼 코드 단위 둘로 표현되는 문자를 하나의 유니코드 코드 포인트로 다루려면 String.fromCodePoint()가 더 알맞습니다.
String.fromCharCode()의 올바른 호출
String.fromCharCode(value1, value2, ...)처럼 String 생성자에 붙여 호출합니다. text.fromCharCode() 형태의 문자열 인스턴스 메서드는 아닙니다. 각 인수는 0부터 65535까지의 UTF-16 코드 단위로 생각하면 됩니다. 여러 숫자를 전달하면 순서대로 결합됩니다.
console.log(String.fromCharCode(72)); // 'H'
console.log(String.fromCharCode(72, 69, 76, 76, 79)); // 'HELLO'
console.log('H'.charCodeAt(0)); // 72: 반대 방향의 읽기
원래 글에는 charCodeAt()의 문법과 예제만 있어 두 메서드가 섞여 있었습니다. fromCharCode()는 숫자에서 문자열을 만들고, charCodeAt()은 문자열의 한 위치에서 숫자를 읽습니다. charAt()과 charCodeAt()으로 위치별 값 읽기에서 읽는 방향을 더 자세히 비교할 수 있습니다.
UTF-16 단위와 코드 포인트 구분하기
fromCharCode()는 인수를 16비트 코드 단위로 취급합니다. 65535를 넘는 숫자를 하나 넣어도 전체 코드 포인트를 자동으로 변환하지 않고 아래 16비트만 사용합니다. BMP 밖의 문자를 지정할 때는 코드 포인트 전체를 받는 fromCodePoint()를 사용하세요.
const point = 0x1F642;
const face = String.fromCodePoint(point);
console.log(face.length); // 2: UTF-16 단위 두 개
console.log(face.charCodeAt(0)); // 55357
console.log(face.charCodeAt(1)); // 56898
console.log(String.fromCharCode(55357, 56898) === face); // true
console.log(String.fromCharCode(point) === face); // false
서로게이트 쌍을 이미 UTF-16 단위 두 개로 갖고 있다면 fromCharCode()에 두 값을 전달할 수 있습니다. 하나의 코드 포인트를 가진 상황에서는 fromCodePoint()가 의도를 더 정확하게 표현합니다. MDN의 String.fromCharCode() 문서와 String.fromCodePoint() 문서를 참고하세요.
유효하지 않은 입력을 처리하기
fromCharCode()는 65535보다 큰 인수를 자동으로 잘라 쓰므로 사용자 입력을 그대로 넘기면 예상과 다른 글자가 나올 수 있습니다. 코드 단위 값이 필요한 작업이라면 입력을 정수 0~65535 범위로 확인하세요. 코드 포인트를 받아야 하는 경우에는 fromCodePoint()와 그 함수의 범위 검사를 사용하세요.
function codeUnitToText(value) {
if (!Number.isInteger(value) || value < 0 || value > 65535) {
throw new RangeError('UTF-16 코드 단위 범위가 아닙니다.');
}
return String.fromCharCode(value);
}
console.log(codeUnitToText(72)); // 'H'
이 검사는 이 글의 “UTF-16 코드 단위 입력”이라는 목적에 맞춘 것입니다. 유니코드 코드 포인트 전체를 일부러 받아야 한다면 상한을 65535로 고정하지 말고 fromCodePoint() 쪽의 입력 규칙을 적용하세요.
전체 예제: 숫자 목록을 문자열로 바꾸기
아래 코드를 UTF-8로 string-from-char-code.html에 저장해 브라우저에서 엽니다. 쉼표로 나눈 숫자를 입력하고 버튼을 누르면 만든 문자열과 charCodeAt()으로 다시 읽은 코드 단위가 표시됩니다. 빈 항목·소수·범위 밖 숫자는 오류로 표시됩니다.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>UTF-16 코드 단위로 문자열 만들기</title>
</head>
<body>
<label for="units">UTF-16 코드 단위 (쉼표로 구분)</label>
<input id="units" type="text" value="72, 69, 76, 76, 79">
<button id="convert" type="button">문자열 만들기</button>
<pre id="output" aria-live="polite"></pre>
<script>
const units = document.querySelector('#units');
const output = document.querySelector('#output');
function convert() {
const parts = units.value.split(',').map(part => part.trim());
const values = parts.map(part => Number(part));
if (parts.some(part => part === '') ||
values.some(value => !Number.isInteger(value) || value < 0 || value > 65535)) {
output.textContent = '0~65535의 정수를 쉼표로 구분해 입력하세요.';
return;
}
const text = String.fromCharCode(...values);
output.textContent = `문자열: ${JSON.stringify(text)}\n` +
`다시 읽은 UTF-16 값: ${Array.from({ length: text.length },
(_, index) => text.charCodeAt(index)).join(', ')}`;
}
document.querySelector('#convert').addEventListener('click', convert);
convert();
</script>
</body>
</html>
기본 입력 72, 69, 76, 76, 79의 결과는 "HELLO"입니다. 65, 66으로 바꾸면 "AB"가 나옵니다. 65536을 입력하면 자동으로 잘린 문자를 보여 주는 대신 범위 오류를 알려 줍니다. 이모지의 UTF-16 단위 두 개를 알고 있다면 위 코드의 55357, 56898로 동작을 비교할 수 있습니다.




