[CS] 유니코드와 UTF-8

June·2021년 9월 17일
0

[CS] CS 지식 정리

목록 보기
20/27

ASCII

초기에 문자를 표현하던 대표적인 방식은 ASCII 인코딩 방식으로, 1바이트에 모든 문자를 표현했다. 게다가 1 비트는 체크섬으로 제외하여 7비트, 즉 128글자로 문자를 표현했다.

그러다보니 한글이나 한자 같은 문자는 2개 이상의 특수 문자를 합쳐서 표현하곤 했는데, 당연히 이런 방식은 비정상적이며, 경우에 따라서는 깨지거나, 제대로 표현되지 않는 경우가 잦았다. 이런 문제를 해결하기 위해 2~4 바이트의 공간에 여유있게 문자를 할당하고자 등장한 방식이 바로 유니코드이다.

파이썬이 버전 3으로 넘어오면서 가장 큰 변화 중 하나는 바로 문자열의 처리 방식이다. 파이썬 2 이전에는 한글을 비롯한 특수 문자들이 모두 별도로 인코딩되는 구조라서, 콘솔에서 원래 값을 출력하기가 쉽지 않았다. 그러나 파이썬 3에 이르러서는 문자열은 모두 유니코드 기반으로 전환됐고, 덕분에 많은 많은 부분이 개선되어 파이썬3부터는 영어뿐만 아니라 한글, 한자 등의 다국어를 출력하는데 아무런 불편함이 없다.

UTF-8

이제 유니코드의 가변 길이 문자 인코딩 방식인 UTF-8의 내부구조를 살펴보자.

만약 모든 문자를 4바이트로 표현하면 Python이라는 영문 문자열은 24바이트의 메모리를 차지한다.

그런데 이 방식은 메모리 낭비다. 이 문제를 해결하기 위해 가변 인코딩 방식이 등장했고, 그중 가장 유명한 방식이 바로 UTF-8이다.

시작 비트를 보면 문자의 전체 바이트를 결정할 수 있다. 첫 바이트의 맨 앞 비트를 확인해서 0인 경우 1바이트, 10인 경우 특정 문자의 중간 바이트, 110인 경우 2바이트, 110인 경우 3바이트, 11110인 경우 4바이트 이런 식이다.

여기서 중요한 점은 유니코드의 값에 따라 가변적으로 바이트를 결정하여 불필요한 공간 낭비를 절약할 수 있다라는 점이다.

앞서 Python이라는 문자열도 모두 ASCII 문자 범위 내에 있으므로 UTF-8 인코딩으로는 6바이트에 표현이 가능하다

파이썬은 3 버전부터 유니코드로 모든 문자열을 표현한다고 했지만, 사실 파이썬에서는 내부적으로는 UTF-8 인코딩을 사용하지는 않는다. 왜 그럴까? 그 이유는 인덱스를 통해 개별 문자에 접근하기가 어렵기 때문이다.

만약 문자열을 UTF-8으로 인코딩해둔다면 각 문자마다 바이트 길이가 달라지게 되므로, 전체 문자열을 스캔하지 않는 한 원하는 인덱스에 빠르게 접근할 수 없다.

따라서 모든 문자열이 ASCII 범위 내에 있다면 Latin-1 인코딩(1바이트 인코딩)을 사용하고, 이외의 대부분 문자열은 UCS-2(고정 2바이트 인코딩)로 2바이트 인코딩을 한다. 특수 기호, 그림 이모티콘, 희귀 언어 등이 포함되었다면 UCS-4(고정 4바이트 인코딩)로 4바이트 인코딩을 한다.

이처럼 각 문자열에 포함된 문자 범위에 따라 서로 다른 고정 인코딩 방식을 택함으로써, 내부적으로 파이썬은 문자열 슬라이싱을 포함한 원하는 인덱스에 빠르게 접근할 수 있는 방식을 택하고 있다.

0개의 댓글