유니코드

전세계의 문자를 컴퓨터에서 일관되게 표현하기 위한 산업표준 문자 표기 방식이다.

유니코드는 코드 포인트(code point) 라는 단일 단위로 문자를 표현하며 이에 대한 테이블은 위키나 기타 사이트에서 확인 가능하다.

위키페디아 코드 포인트 테이블

유니코드의 코드포인트는 U+10FFFF 까지 할당되어 있고 한글은 U+AC00 ~ U+A87F 까지 지정되어 있다. (여기 참고)

UTF

Unicode Transformation Format 은 유니코드를 위한 가변길이 문자 인코딩 방식으로 코드포인트에 등록된 문자 하나를 표현하기 위해 1 ~ 4 바이트를 사용한다.

UTF-8 은 1~4바이트를 사용하고 UTF-16 은 2,4바이트를 사용한다. UTF-32 는 잘 사용되지 않는다.

간략하게 UTF-8, UTF-16 만 살펴보자면 일단 인코딩 방식은 아래와 같다.

코드 범위 UTF-8 UTF-16
000000 - 00007F 0xxxxxxx 00000000 0xxxxxxx ASCII 와 동일
000080 - 0007FF 110xxxxx 10xxxxxx 00000xxx xxxxxxxx 첫 바이트는 110 또는 1110 으로 시작, 나머지는 10 으로 시작
000800 - 00FFFF 1110xxxx 10xxxxxx 10xxxxxx xxxxxxxx xxxxxxxx
010000 - 10FFFF 11110zzz 10zzxxxx 10xxxxxx 10xxxxxx 110110yy yyxxxxxx 110111xx xxxxxxxx UTF-16 surrogate pair 영역 (yyyy = zzzzz - 1). UTF-8 로 표시된 비트 패턴은 실제 코드 포인트와 동일

<위키페디아 참조>

예를 들어 한글 “위” (U+C704) 는 아래와 같은 방법으로 UTF-8 로 인코딩 된다.

  • U+8000 - U+FFFF 사이 영역이므로 위 표에 따라 1110xxxx 10xxxxxx 10xxxxxx 형식의 3바이트로 표시될 것이다.
  • 16 진수 C704 는 2진수 11000111 00000100 이다.
  • 이 비트들을 x 자리에 끼워 넣으면 11101100 10011100 10000100 이 된다.
  • 결과적으로 3바이트가 되며 16진수로 표시하면 EC 9C 84 가 된다.

UTF-8 특징

UTF-8 은 아래의 특징을 가진다.

  • 1바이트로 표시된 문자의 최상위 비트는 항상 0이다.
  • 2바이트 이상으로 표시된 문자의 경우, 첫 바이트의 상위 비트가 그 문자를 표시하는데 필요한 바이트 수를 나타낸다. 예를 들어 2바이트는 110 으로 시작하고 3바이트는 1110 으로 시작한다.
  • 첫 바이트가 아닌 나머지 바이트의 상위 2비트는 항상 10 이다.

이런 규칙으로 설계한 이유는 어떠한 상황에서도 한 문자에 대한 비트표현이 다른 문자의 비트표현의 일부가 되는 경우가 없도록 하기 위함이다.

이로 인하여 얻는 장점은 아래와 같다.

  • 어떤 텍스트에서 부분 문자열을 찾는 (바이트 단위의) 알고리즘을 쉽게 적용할 수 있다.1)
  • 하나 이상의 바이트들이 손실되어도 다음의 정상 문자를 찾아내어 피해를 줄일 수 있다.

FAQ

  • UTF8 로 인코딩된 파일을 불러올 때 첫 3바이트의 값이 무조건 -17, -69, -65 (0xEF, 0xBB, 0xBF) 이다. 이를 해결하는 방법은?
    • 일부 텍스트 편집기의 경우 (윈도우즈의 notepad 같은) UTF8 포멧으로 저장할 때 BOM(byte order mark) 을 첫부분에 저장을 한다. 따라서 첫 3바이트를 무시하거나 아니면 notepad++ 과 같이 BOM 을 없애주는 기능이 있는 편집기를 사용한다.
1) 통합 완성형, Shift JIS, Big5 와 같이 ISO2022 체계에 부합하지 않는 이전의 가변길이 인코딩은 이러지 않아 더 복잡한 알고리즘이 필요하다. 왜냐하면 이들 인코딩은 ASCII 영역의 글자가 2바이트로 표현되는 다른 문자의 두번째 바이트에 사용되기 때문이다.