메아리 저널

Shift-JIS 인코딩 요약

어디 쓸 일이 있어서 Shift-JIS 인코딩을 들여다 보고 있었다. 혹시나 필요하신 분을 위해 간단한 요약을 올려 본다. 변환 테이블 같은 것은 물론 따로 찾아 보셔야 한다. -_-;;; (사실 오픈룩 CJK 페이지가 이런 용도로 좋긴 한데 Shift-JIS에 관련된 건 하나도 없더라. -_-;)

일본의 문자셋은 JIS X 0201, JIS X 0208 등이 있는데, (0212, 0213 같은 건 내 관심사가 아니니깐 위의 링크를 찾아 보시길;) JIS X 0201은 70년대(!)에 지정된 반각 카타카나 문자셋으로 0x80 아래의 문자는 ASCII에서 역슬래쉬를 엔화 기호로 바꾼 것 정도이고, 0xa1부터 0xdf까지는 반각 카타카나가 배정되어 있는 형식이다. JIS X 0208은 대표적인 94×94 문자셋으로 전각 특수문자, 히라가나, 카타카나, 한자 등등이 들어 있는 문자셋이다. (94행이라고는 하지만 실제로는 84행까지만 차 있다.)

안타깝게도 JIS X 0201이 가능한 첫 바이트의 대부분을 먹어 버렸기 때문에, JIS X 0201과 호환되면서 JIS X 0208을 끼워 넣을 수 있게 만들기 위해서 만들어진 인코딩이 Shift-JIS이다. shift라는 말에서도 알 수 있듯이 이 인코딩은 94×94 문자셋을 간단한 계산으로 0x81부터 0x9f까지, 그리고 0xe0부터 0xef까지의 첫 바이트에 구겨 넣어 버리는 방법을 사용한다. 첫 바이트가 47종류가 될 수 있기 때문에 둘째 바이트는 (94 × 94) ÷ 47 = 188종류가 될 수 있는데, 이 놈은 0x80 위에다 낑겨 넣을 수가 없기 때문에 0x40부터 0x7e까지, 0x80부터 0xfc까지(0x7f는 ESC라서 빠짐)로 나눠서 넣는 것이다. 이 영역에 행/열 순서대로 문자를 배치하면 어떻게든 94×94 문자셋을 끼워 넣을 수 있는 것이다. 이러고도 남아 도는 0xf0 위의 영역은 사용자 정의 영역으로 쓰인다.

Shift-JIS에는 다양한 변종-_-들이 있는데, 예를 들어서 휴대폰 업체들에서는 0xf3부터 0xf9까지의 영역에 그림 문자들을 마구 집어 넣었다고 한다. 그 중 가장 잘 쓰이는 게 마이크로소프트의 입김으로 만들어진 cp932이다. (IANA였던가에는 Windows-31J라는 이름이 붙어 있다.) 처음에 이 인코딩은 Shift-JIS에 일부 문자를 바꾸거나 추가한 것이었으며, 0x81, 0x87의 특수문자가 바뀌었고, 원래 JIS X 0208의 안 쓰는 영역이던 0xed, 0xee에 문자를 추가했으며, 마지막으로 0xfa, 0xfb, 0xfc에다가 글자들을 더 추가해 넣은 것이다. 정확하게 말하면 이건 원래 NEC, IBM에서 만든 확장들을 종합해 넣은 셈이긴 하다. cp932는 윈도우 버전에 따라서 계속 조금씩 바뀌었는데, 윈도우 2000의 경우 잘못된 첫 바이트인 0x80, 0xa0, 0xfd, 0xfe, 0xff에 대한 매핑이 따로 있으며, 윈도우 XP의 경우 0xf0부터 0xf9까지의 영역을 유니코드 사용자 영역에 U+E000부터 U+E757까지 순서대로 매핑하고 있다.

개인적으로 Shift-JIS의 가장 큰 단점은 인코딩 감지가 힘들다는 데 있다고 생각한다. 실질적으로 JIS X 0208은 85×94(-_-;;) 문자셋이기 때문에 조금만 고치면 2바이트 시퀀스의 첫 바이트와 둘째 바이트가 모두 0x80 위에 있도록 만들 수 있었을텐데 말이다. (물론 JIS X 0208을 고대로 가져 오면 꿈도 못 꿀 일이다.) 뭐 당시에는 자국 안에서만 쓴다고 가정했을 테니까 이해는 가지만 인코딩 제정할 때 좀 더 "선견지명" 같은 게 있었다면 세상은 좀 더 행복해졌으리라 생각한다. (응?)

이 글은 본래 http://tokigun.net/blog/entry.php?blogid=79에 썼던 것을 옮겨 온 것입니다.


(rev 553c824afb91)