- 아스키(ASCII) 코드란?
American Standard Code for Information Interchange의 약자로, 0~127까지 7비트로 문자를 표현하는 코드이다. 나머지 1비트는 오류를 검출하는 패리티 비트이다.
이름에서 알 수 있듯 American, 즉 미국의 표준이라 영어 외의 언어는 포함되어 있지 않다.
- 유니코드란?
각국의 컴퓨터는 아스키 코드와 같이 자국어만 지원하는 각기 다른 코드를 사용하고 있었다. 그러나 인터넷을 통해 전세계의 컴퓨터가 연결되면서 코드가 상이해 정보 교환이 어려운 문제가 대두되었고, 이를 해결하기 위한 표준으로 유니코드가 등장하였다.
유니코드는 전세계의 언어를 하나의 코드 체계로 집약하였다. 초기에는 2바이트로 설계되었으나, 2바이트로는 부족하여 4바이트를 사용하고 있다.
한글은 본래 초성, 중성, 종성의 조합으로 이루어지는 언어이다. 이에 유니코드가 도입되기 전에는 조합형을 사용하자는 의견과 완성형을 사용하자는 의견이 대립하였는데, (https://namu.wiki/w/조합형%20완성형%20논쟁 참고) 결과적으로는 완성형이 채택되었다. 사진과 같이 각각의 완성자에 코드 값(혹은 코드 포인트)을 할당하였는데, 그 개수가 무려 1만을 넘는다고 한다..
- 유니코드의 인코딩 방식
유니코드는 그 자체로도 정보 교환에 사용될 수 있지만 그다지 효율적이지는 않다. 가장 많이 사용되는 문자인 알파벳은 1바이트로도 충분히 표현될 수 있어, 굳이 4바이트로 전송할 필요가 없기 때문이다. 이에 주로 사용되는 인코딩 방식이 UTF-8과 16이다. (UTF-32는 유니코드를 그대로 전송하는 식이므로 거의 사용되지 않는다.) 프로그래밍 언어인 Java가 내부적으로 UTF-16을 사용하고 있다.
- UTF-16
UTF는 Unicode Transformation Format의 약자로, 말그대로 유니코드를 변환하기 위한 포맷이다. 그 중 UTF-16은 16비트, 즉 2바이트 단위로 가변적인 포맷인데,
0x0 ~ FFFF 범위의 문자는 2바이트로 전송하고,
0x10000 ~ 10FFFF 범위의 문자는 4바이트로 전송하는 방식이다.
2바이트로 전송할 경우 해당 코드는 변환할 필요가 없다. 다만, 아키텍처에 맞게 엔디안을 지정할 수 있고 각각을 UTF-16 BE(Big Endian), UTF-16 LE(Little Endian)라고 칭한다.
문서 앞에는 0xFEFF 라는 BOM(Byte Order Mark)을 삽입하여 디코더가 엔디안을 구분할 수 있도록 한다. 만약 FE, FF의 순서가 뒤바뀔 경우 Little Endian으로 판단할 수 있다.
2바이트의 예시로서 '강'을 UTF-16으로 변환해보겠다. '강'의 유니코드 값은 위 그림에서 알 수 있듯 0xAC15 로 0x0 ~ FFFF 범위 내에 있다. 따라서 0x[AC 15] 로 그대로 전달하거나(BE), 0x[15 AC] 로 전달할 수 있다(LE).
4바이트로 전송할 경우 서로게이트(Surrogate) 페어로 변환되어 전송된다. 여기서 변환 공식은 다루지 않는다.
- UTF-8
UTF-8은 8비트, 즉 1바이트 단위로 가변적인 포맷이다. 최소 1바이트에서 최대 4바이트까지 늘어날 수 있다. 아래는 인코딩 규칙이다.
코드 범위 | 사용 비트 개수 | 1번째 옥텟 | 2번째 옥텟 | 3번째 옥텟 | 4번째 옥텟 |
0x0 ~ 7F | 0 ~ 7개 | 0xxx xxxx | |||
0x80 ~ 7FF | 8 ~ 11개 | 110x xxxx | 10xx xxxx | ||
0x800 ~ FFFF | 12 ~ 16개 | 1110 xxxx | 10xx xxxx | 10xx xxxx | |
0x10000 ~ 0x10FFFF | 17 ~ 21개 | 1111 0xxx | 10xx xxxx | 10xx xxxx | 10xx xxxx |
코드 범위는 유니코드의 범위를 말한다. 0x0 ~ 7F 의 경우 아스키 코드와 값이 일치하여, 아스키 코드를 사용하는 것과 동일하게 사용할 수 있다. 이후 범위부터는 코드의 길이를 나타내는 헤더(110, 1110, 11110)와 바디임을 나타내는 헤더(10)을 조합한 옥텟의 시퀀스로 표현된다. x는 코드 값이다.
예시로서 '감'을 UTF-8로 변환해보겠다. '감'은 0xAC10 이므로 0x800 ~ FFFF 의 범위에 속한다. 그리고 0xAC10 을 이진수로 나타내면 [1010 1100 | 0001 0000] 이므로 아래와 같이 작성할 수 있다.
[1110 1010 | 1011 0000 | 1001 0000] = 0x[EA B0 90]
빨간색은 헤더 값이고, 파란색은 유니코드 값이다. 코드 값을 순서대로 x에 대입하여 변환한다.
UTF-8도 UTF-16처럼 EF BB BF 라는 BOM이 존재하지만 거의 사용되지 않는다. 별도의 시퀀스 형식으로써 엔디언이라는 개념이 불필요하기 때문이다. 다만 일부 프로그램에서는 BOM이 없는 UTF-8 파일을 잘못 인식하는 경우가 있어, 인코딩을 구분하기 위한 목적으로 드물게 사용된다.
'CS > 기타' 카테고리의 다른 글
컴파일러와 인터프리터 (+ JIT 컴파일러) (0) | 2024.12.05 |
---|---|
정지 문제(Halting problem)의 간단한 증명 (0) | 2023.04.28 |
빅 엔디안과 리틀 엔디안을 직접 확인해보자 (0) | 2023.02.04 |
부동소수점의 정밀도 문제에 대하여 (0) | 2022.10.28 |
댓글