Windows Character Encoding: UCS2? UTF-16?

예전에 문자집합;character-set 과 인코딩에 관해서 일련의 포스팅을 했다(#1, #2, #3). 그런데 어제부터 Windows via C/C++ 이란 책을 읽고있는데, 내가 잘못 알고 있던 부분을 발견해서 이전 포스팅에 대한 정정 포스팅.

Windows에서는 UCS-2 인코딩을 사용한다

라고 했었는데 사실이 아닙니다.

Windows는 2000과 그 이후의 버젼들에서 모두 UTF-16 기반으로 동작하며, 그 이전의 NT 커널들만 UCS-2 기반.

여튼 그런 연유로 저 둘을 다시 부연 설명하자면,

  • 둘 다 기본적으론 글자당 2bytes 를 할당하는 형태
  • UCS-2는 글자당 무조건 2bytes만 쓴다. 그보다 길게는 쓸 수 없는 고정길이 인코딩. BMP1 만 표현.
  • UTF-16은 그 이상2을 표현할 수 있는 방법 — surrogate pair라는 것을 제공한다. 그래서 한 글자의 길이가 4 bytes가 되는 경우가 존재한다. 정도다. Windows 에서는 UTF-16에 기반한 Unicode를 지원하며, SQL 서버들과는 좀 다르다. MS SQL서버는 내가 아는 범위에선 아직 UCS-2 위주로 동작한다.

ps. 제목과는 좀 연관없는 얘기지만, Windows via C/C++ 에서 앍게된 사실 하나 더.

Windows Vista 이후의 OS는 완전히 UTF-16 모드로 동작하게 되었고, 소위 ANSI 함수들은 래퍼로만 남게 되었다. CreateWindowA, 처럼 끝에 A가 붙는 함수들3 의 경우에는 ANSI문자열(=MBCS 문자열)을 받아들이는 함수였는데, 이젠 정말로 래퍼 수준으로 전락해서 단순히 문자열 인자를 UTF-16 인코딩으로 변환해서 Windows System Call이나 API 함수를 호출하는 역할을 하게 되었다.

Windows Vista / Server 2008 성능을 원한다면 UTF-16 (=wide character API) 를 쓰라는 것.


  1. U+0000~U+FFFF 까지의 영역만 표현할 수 있다. 가장 기본적인 문자집합에 해당하며, 이런 부분만 표현하기 때문에 UCS-2는 고정길이가 가능해진다. 그리고 고정길이이기 때문에 Database 처럼 문자열 처리 속도가 아주 빨라야하는 응용에서는 꽤 널리 사용된다. ↩︎

  2. plane 0인 BMP말고 그 이상의 것(plane 1~15)들 까지. ↩︎

  3. 특히 CreateWindowW처럼 W로 끝나는 소위 Wide 함수들과 대응해서. ↩︎