조엘 온 소프트웨어의 [유니코드와 문자집합에 대한 고찰] 절을 읽고,
컴퓨터에서 문자를 어떤식으로 다루는지 정리 할 필요가 있다고 느껴졌다.
책에서는 이 주제를 얘기하기 위해 ASCII 에 관한 얘기부터 시작한다.
ASCII 코드
위키에 나온 정의에 따르면 다음과 같다.
미국정보교환표준부호(영어: American Standard Code for Information Interchange),
또는 줄여서 ASCII( /ˈæski/, 아스키)는 영문 알파벳을 사용하는 대표적인 문자 인코딩이다
쉽게 말하면 총 7개의 비트로 영문 알파벳, 숫자, 기타 부호를 표현하기 위한 문자 인코딩 방식이다.
7bit 로 이루어져 있어서 총 128개의 문자를 표현할 수 있다.
정확히는
- 33개의 출력 불가능한 제어 문자들
- 공백을 포함한 95개의 출력 가능한 문자들
(영문 알파벳 대소문자 + 10개의 숫자 + 32개의 특수문자 + 하나의 공백문자)
로 이루어져 있다.
여기서 제어 문자들은 역사적인 이유로만 남아있고, 대부분은 더 이상 사용되지 않는다고 한다.
ASCII 코드표
https://ko.wikipedia.org/wiki/ASCII 참고
표를 보면 실제 출력 가능한 문자들은 십진수 기준으로 32 ~127 까지이다.
코드 페이지
대다수의 컴퓨터는 8bit 인 바이트 단위를 사용한다.
문자를 표현할 때 ASCII 는 7bit 만 사용하므로 1bit 는 자유자재로 쓸 수 있게 된것이다!
128 ~ 255 사이의 글자의 정의는 각자의 용도에 맞게 정의 되었다.
지역에 따라 128 이상의 문자를 다루는 방식이 달랐고, 이런 시스템을 코드 페이지 라고 부른다.
영어는 코드 페이지 437, 한국은 949 를 사용한다.
각 코드 페이지는 128 미만에 위치한 글자는 모두 동일하지만, 128 이상의 글자들은 국가별로 모두 다르다.
주로 MS-DOS 같은 OS 에서 쓰인다고 한다.
그러나 이 8bit 로도 각국의 문자들을 모두 표현하기에는 부족했다...
그래서 나온 것이 유니코드 다.
유니코드
위키에 나온 정의를 보자면,
유니코드는 전 세계의 모든 문자를 컴퓨터에서 일관되게 표현하고 다룰 수 있도록 설계된 표준이다.
즉 모든 문자를 컴퓨터에서 표현하기 위해 마련한 1:1 코드표 이다.
각 알파벳, 문자에 존재하는 관념적인 철자마다 고유 번호를 붙여놓았고, U+0645 이런 식으로 표현한다.
여기서 U+ 는 유니코드 를 의미하고, 번호는 코드 포인트 라고 한다. 번호는 16진수로 표현한다.
HI 를 유니코드로 표현하면,U+0048 U+0049
가 된다.
그럼 이제 코드 포인트 숫자를 각각 두 바이트로 저장하면 되겠다! 했지만...
이 또한 다른 문제들이 생겼고 (책에서는 리틀엔디안,빅엔디안 방식을 예로 들었다),
이런 문제들은 인코딩 방법들이 나오면서 해결됐다.
인코딩
인코딩은 유니코드 코드 포인트를 따르는 문자열을 컴퓨터에 저장하는 방법을 말한다.
이 인코딩 방식 중 하나가 많이 들어본 UTF-8 이다.
UTF-8
각 글자(코드 포인트) 마다 바이트가 다른 가변 인코딩 방식이다.
코드 범위 16진수 최소 ~ 최대 | 이진수 바이트 배열 |
---|---|
00000000 ~ 0000007F | 0xxxxxxx |
00000080 ~ 000007FF | 110xxxxx 10xxxxxx |
00000800 ~ 0000FFFF | 1110xxxx 10xxxxxx 10xxxxx |
00010000 ~ 001FFFFF | 11110xxx 10xxxxxx 10xxxxx 10xxxxxx |
00200000 ~ 03FFFFFF | 111110xx 10xxxxxx 10xxxxx 10xxxxxx 10xxxxx |
0 ~ 127 사이 ( ~ U+007F) 의 코드 포인트는 1바이트로 저장한다. (위 표의 첫번째 행 참고)
즉 7bit ASCII 문자와 동일한 방식으로 표현된다.
128 이상의 코드 포인트만 2, 3 바이트에서 시작해서 최대 한계인 6 바이트까지 확장해서 저장한다.
원래 UTF-8 은 6바이트를 사용해 U+7FFFFFFF
까지의 코드 포인트를 표현 할 수 있게 했으나,
유니코드에서 실제로 정의하는 U+10FFFF
까지의 문자만을 표시할 수 있도록 제한했다.
실제 인코딩
U+C704 ( 유니코드 상에서 한글 '위' 를 나타낸다.) 를 UTF-8 방식으로 인코딩 하는 방식을 알아보자.
1) U+0800 ~ U+FFFF
사이의 영역에 있으므로 표에 따라 1110xxxx 10xxxxxx 10xxxxx
형식으로 인코딩 된다.
2) 16진수 C704 는 2진수로 표현하면 1100 0111 0000 0100
과 같다.
3) 2진수로 바꾼 비트들은 순서대로 x
에 표시된 비트에 들어간다.
11101100 10011100 10000100
4) 결과적으로 3바이트로 인코딩 되며 16진수로 표현하면 EC 9C 84
가 된다.
EUC-KR
EUC-KR 은 한글을 표현하기 위해 나온 인코딩 방식이다.
1~127 까지는 ascii 코드와 동일하다.
그 이상은 정해진 문자집합 (한글 포함)을 표현하고, 2byte 로 표현한다.
KS X 1001 문자집합을 사용한다.
ascii 처럼 각 문자에 대응하는 값이 있는 식이다.
예를 들어 '위' 라는 글자는 C0 A7 로 표현된다.
보통 웹상에서 한글이 깨지는 이유는 브라우저의 인코딩 방식과 서버에서 준 페이지의 인코딩 방식이 달라서다.
예를 들어 서버는 euc-kr 방식으로 인코딩을 해서 줬는데, 브라우저가 utf-8 방식을 사용하고 있는 식이다.
그러면 브라우저는 utf-8 로 디코딩을 할 것이고, 글자가 다 깨져서 보이는 것이다.
참고
- 조엘 온 소프트웨어
- 위키백과
피드백 환영 합니다. :)