2022. 4. 24. 17:04ㆍCommon
ASCII
ASCII는 숫자, 영어의 알파벳, 몇몇 특수문자에 0-127 각각의 수를 할당한 것이다.
0~127 범위의 수를 사용하기 때문에 7bit로 표현이 가능하며, 따라서 각각의 문자는 메모리에 1byte로 저장할 수 잇다.
ANSI
ASCII는 언어를 영어밖에 표현하지 못하는 문제가 있다.
하지만, ASCII에는 1bit를 사용하지 않는 것을 알기 때문에 이를 활용하여 Code Page라고 하는 것을 도입했는데, 0-127 범위는 ASCII와 똑같고, 128-255 범위의 수들은 각각의 Code Page에 따라 다른 문자들을 할당한 것이다.
ANSI라고 부르면 따로 고정된 Code Page를 칭하는 것은 아니며, 보통 "내 시스템의 Default Locale/Code Page"를 의미한다. 즉, 시스템에 따라 Code Page가 다르기 때문에 128-255에 할당된 문자를 사용하는 경우 의도치 않은 결과가 나올 수 있다.
Unicode
우리는 Unicode에 대해 흔히 잘못 알고 있는 것이 있는데, 바로 Unicode를 특정 인코딩이라고 알고 있는 것이다. Unicode는 인코딩이 아니라 Character Set이며, 그렇기 때문에 Unicode가 메모리에서 2byte를 차지한다는 것은 잘못된 정보이다. Unicode는 Character Set에 있는 각각의 문자에 고유한 수를 할당하는데, 이 수를 Code Point라고 한다. 이 Code Point를 메모리에 어떻게 표현되는지를 결정하는 것이 아래에서 소개 할 UCS-2, UTF-8, UTF-16과 같은 인코딩이다.
UCS-2
Code Point는 다음과 같이 표현된다.
U+XXXX
U+는 Unicode를 뜻하고, XXXX는 16진수의 수이다.
다음 문자열을 보자.
Hello
이 문자열은 Unicode로 다음과 같이 표현할 수 있다.
U+0048 U+0065 U+006C U+006C U+006F
이제 이 Code Point들을 메모리에 저장해보자.
우리는 간단히 각 Code Point 당 2byte를 할당하여 다음과 같이 저장할 수 있다.
00 48 00 65 00 6C 00 6C 00 6F
하지만 다음과 같은 방법도 가능하다.
48 00 65 00 6C 00 6C 00 6F 00
CPU의 Endianness(Big-Endian/Little-Endian)에 따라 두 방법 중 각 Endianness에 맞는 방법을 선택해서 사용 할 수 있으면 좋을 것 이다. 하지만 두 방법을 구별할 수 있는 수단이 필요했기 때문에 맨 앞에 FE FF를 붙였으며, FF FE를 붙이는 경우에는 바이트를 스왑해야 하는 것을 인식할 수 있었다. 이것을 Unicode Byte Order Mark라고 한다.
그런데, 위에 2byte씩 할당된 메모리들을 보면 00들로 인해 절반 가량의 메모리가 낭비되는 것을 볼 수 있다. 이러한 문제를 해결하기 위해 UTF-8 인코딩이 발명되었다.
UTF-8
이 인코딩은 0-127 범위의 Code Point들은 1byte에 저장하고, 나머지는 2byte에서 최대 4byte까지 사용하여 저장하는 가변 크기의 인코딩 방식이다. 따라서 Hello 문자열을 메모리에 저장됐을 때 다음과 같이 ASCII와 호환이 된다는 장점이 있다.
48 65 6C 6C 6F
UTF-16
이 인코딩은 가변 크기의 인코딩 방식으로, UCS-2 인코딩과 유사하지만 각 문자를 표현하는데 2byte 또는 4byte를 사용한다는 점에서 2byte 만을 사용하는 고정 크기의 UCS-2 인코딩과 다르며, 표현할 수 있는 문자의 개수도 상당히 많아졌다. 하지만, 위에서 말했던 Endianness를 고려해줘야 된다는 점과, ASCII 인코딩과 호환이 되지 않는 문제가 있다.
(ASCII는 1byte를 사용하고 UTF-16은 최소 2byte 이므로)
[참고]
- https://stackoverflow.com/questions/700187/unicode-utf-ascii-ansi-format-differences
- https://stackoverflow.com/questions/2281646/whats-the-difference-between-encoding-and-charset