유니코드와 UTF-8

    1. ASCII Encoding

    - 1 byte (8 bit) 중 Checksum으로 1 bit를 제외한 총 7 bit로 문자를 표현

    - 한글이나 한자의 경우 2 개 이상의 특수문자를 합쳐서 표현하기 때문에 글자가 자주 깨짐

     

    2. Unicode

    - 2-4 byte 공간에 여유있게 문자 할당

    - 문제점) 1 byte로 표현 가능한 문자(영어, 숫자)도 필요 이상의 공간을 할당해 메모리 낭비가 심함

     

    3. UTF-8

    - Unicode의 가변길이 문자 인코딩 방식: 불필요한 공간의 낭비를 줄일 수 있음

    - 표) UTF-8 byte 순서의 이진 포맷

    byte 수 byte 1 byte 2 byte 3 byte 4
    1 0xxx xxxx      
    2 110x xxxx 10xx xxxx    
    3 1110 xxxx 10xx xxxx 10xx xxxx  
    4 1111 0xxx 10xx xxxx 10xx xxxx 10xx xxxx

    - 시작 bit를 확인해 전체 byte 결정할 수 있음. 첫 바이트의 맨 앞 비트를 확인해, 

      - 0인 경우 1 byte

      - 10인 경우 특정 문자의 중간 바이트

      - 110인 경우 2 byte

      - 1110인 경우 3 byte

      - 1111 0인 경우 4 byte

     

    예시)

       유니코드 A: 0x0041

    15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1

       UTF-8 A: 0x41

    7 6 5 4 3 2 1 0
    0 1 0 0 0 0 0 1

      유니코드 $\pi$: 0x03C0

    15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0

       UTF-8 $\pi$: 0xCF 0x80

    7 6 5 4 3 2 1 0
    1 1 0 0 1 1 1 1
    7 6 5 4 3 2 1 0
    1 0 0 0 0 0 0 0

      유니코드 '한': 0xD55C

    15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
    1 1 0 1 0 1 0 1 0 1 0 1 1 1 0 0

       UTF-8 '한': 0xED 0x95 0x9C

    7 6 5 4 3 2 1 0
    1 1 1 0 1 1 0 1
    7 6 5 4 3 2 1 0
    1 0 0 1 0 1 0 1
    7 6 5 4 3 2 1 0
    1 0 0 1 1 1 0 0

      Python 3부터 Unicode로 모든 문자열을 표현하지만, 내부적으로 UTF-8 인코딩을 사용하지는 않는다. 인덱스를 통해 개별 문자에 접근하기가 어렵기 때문이다.

     

      파이썬에서는 문자열 슬라이싱을 비롯해 원하는 문자에 인덱스로 접근할 수 있는 다양한 방식을 제공하는데, 만약 문자열을 UTF-8로 인코딩해둔다면 각 문자마다 바이트 길이가 달라지게 되므로 전체 문자열을 스캔하지 않는 한 원하는 인덱스에 빠르게 접근하기 어렵다. 따라서 고정 길이 인코딩 방식이 필요하며, 파이썬은 문자열 단위로 다른 고정 길이 인코딩 방식을 적용해 이 문제를 해결한다. 

     

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

    댓글