Shift_JIS
Shift_JIS는 마이크로소프트와 주식회사 아스키가 합작해서 만든 일본어 문자인코딩이다. JIS X 0201 및 JIS X 0208 문자집합을 지원하는 인코딩이지만, 그 모양새나 쓰임새나 여러 모로 문제가 많은(...) 인코딩이다. 그럼에도 불구하고 마이크로소프트 윈도우의 기본 인코딩이었기 때문에(정확히는, Windows-31J의 형태로) UTF-8이 나올 때까지는 매우 널리 쓰였다.
1982년 발표 당시에는 표준화 과정을 거치지 않은 사실상의 표준(de facto standard)이었으나, 1997년 이후로 JIS X 0208 부속서 1에 "시프트 인코딩"이라는 이름으로 기술되면서 정식으로 표준화되었다. 상용조합형의 표준화 과정을 생각해 보면 비슷할 듯.
배경[편집 | 원본 편집]
Shift_JIS의 등장에는 슬픈 전설이 있다. 나는 전설 따위는 믿지 않아 본래 일본은 문자 전산화를 처음 할 때(무려 1960년대)만 해도 2바이트 인코딩을 위한 체계가 전혀 마련되어 있지 않았기 때문에 가타카나만을 1바이트 인코딩으로 넣어 버리게 되는데, 이게 바로 JIS X 0201(당시에는 JIS C 6220)이다.[1] 그런데 나중에 2바이트 인코딩으로 히라가나, 가타카나 및 칸지를 모두 담은 JIS X 0208(당시에는 JIS C 6226)이 나오는데, 본래의 의도대로라면 JIS X 0208은 JIS X 0201을 "대체"하는 표준이 되었어야 했지만 기존에 작성된 문서가 전혀 호환되지 않는 심각한 문제가 발생하고 만다. 게다가 JIS X 0208은 흔히 볼 수 있는 94x94 문자 집합임에도 불구하고 JIS X 0201이 이미 GR 영역(0xA0~0xFF)을 일부 사용하고 있어서 간단하게 붙여 넣을 수가 없었다. (KS X 1001이 KS X 1003과 말끔하게 결합하여 EUC-KR이 되는 것과는 대조적이다.)
그래서 JIS X 0201에서 할당되지 않은 65개의 바이트를 첫 바이트로 하고, 둘째 바이트의 범위를 크게 늘려 잡아서 JIS X 0208을 인코딩하는 꼼수를 쓴 것이 바로 Shift_JIS이다. "시프트"라는 이름은 JIS X 0208의 행 번호를 1비트 오른쪽 시프트하여 첫 바이트를 정한 점에서 유래한다. 행 번호의 맨 아래 1비트는 열 번호에 합쳐서 두번째 바이트에 인코딩하는데, 이 때문에 두번째 바이트는 94×2 = 188개의 문자를 인코딩해야 했다. 이 때문에 GR 영역은 물론이고 CR(0x80~0x9F) 및 GL(0x20~0x7F) 영역 대부분을 함께 써야 했는데, 물론 온갖 문제가 일어나게 된다. 십수년 뒤에 나온 Windows-949에서도 사실상 같은 접근이 쓰이긴 했지만, Shift_JIS에서 엄청나게 데인 마이크로소프트는 두번째 바이트의 범위를 잘 조정하여 호환성 문제를 상당수 피해 갔다.
이런 혼란은 기본적으로는 일본이 한중일 삼국 중 문자 전산화를 가장 먼저 시작했기 때문에 벌어진 것이지만, 결과적으로는 후술할 문제들 때문에 널리 쓰이긴 해도 완벽하게 다른 모든 인코딩을 대체할 수는 없었다. Shift_JIS는 DOS V 및 윈도우에서, EUC-JP는 유닉스 계열 운영체제에서, 그리고 ISO-2022-JP는 플랫폼 독립적인 상황(HTML 및 MIME)에서 오랫동안 널리 쓰였다. 또한 마이크로소프트는 한중일 문자 인코딩을 모두 자체적으로 재정의했음에도 불구하고 일본어 인코딩만큼은 다른 회사와 보조를 맞출 수 밖에 없었다(게다가 인코딩 설계에 결정적인 역할도 담당하지 못 했다).
구조[편집 | 원본 편집]
JIS X 0201이 할당하고 있던 GR 영역 바이트는 A1
부터 DF
까지로, Shift_JIS의 첫 바이트는 이 영역을 피하여 할당되어 있다. 즉:
- 1행 및 2행에 속하는 문자는
81
을 첫 바이트로, - 3행 및 4행에 속하는 문자는
82
를 첫 바이트로, - ...
- 61행 및 62행에 속하는 문자는
9F
를 첫 바이트로, - 63행 및 64행에 속하는 문자는
E0
을 첫 바이트로, - ...
- 93행 및 94행에 속하는 문자는
EF
를 첫 바이트로 한다.
Shift_JIS의 둘째 바이트는 JIS X 0208에서 두 행에 속하는 188개의 문자를 적절히 쪼개서 할당되어 있다. 즉:
- 홀수행이면서 1열부터 63열까지에 속하는 문자는 순서대로
40
부터7E
까지를 둘째 바이트로, - 홀수행이면서 64열부터 94열까지에 속하는 문자는 순서대로
80
부터9E
까지를 둘째 바이트로, - 짝수행이면서 1열부터 94열까지에 속하는 문자는 순서대로
9F
부터FC
까지를 둘째 바이트로 한다.
...이걸로 설명이 끝나면 참 좋을텐데, 현실은 그렇지 않다. Shift_JIS에는 확장의 여지가 두 군데 남아 있는데, 일단 JIS X 0208에서 할당되지 않고 남아 있는 영역들(9~15행 및 85~94행)이 있고 Shift_JIS에서 첫 바이트로 사용하지 않는 F0
부터 FF
까지의 영역들이 있다. 후자의 경우 JIS X 0208을 95행 이후로 확장했을 경우를 상정해서 95~126행이라고 부르기도 한다. 이 남아 있는 공간들이 워낙 큰데다가, 일본어의 경우 기존 인코딩으로 표현이 불가능한 가이지(外字)의 수요가 높기 때문에 똑같은 Shift_JIS를 쓴다 하더라도 확장된 문자들에 따라서 인코딩이 달라지는 경우가 흔하다. 다음은 Shift_JIS의 주요 확장들과 확장된 문자들의 목록이다:
- IBM 코드페이지 932: 115~119행에 자체 문자 집합에서 JIS X 0208에 포함되지 않은 한자 및 특수 문자를 추가. 후에 DOS V에서 사용된다.
- NEC PC-9800: IBM 확장 문자를 115~119행에서 89~92행으로 옮기고, 9~13행에 NEC 자체 문자 집합(JIPS GL영역)에 있던 특수 문자를 추가.
- Windows-31J: 윈도3.1 이후로 사용되기 시작한 마이크로소프트 확장. 당시 가장 널리 쓰이던 OEM 문자 집합인 IBM 및 NEC 확장을 합친 것으로, 덕분에 IBM 확장 문자는 두 번 중복으로 들어 간다.[2]
- MacJapanese: 위에 나온 것들과 완전히 다른 확장이다(...). 9~15행에 특수 문자를, 85~89행에 세로쓰기를 위한 90도 회전 문자를 배치했으며, JIS X 0201에서 할당되지 않았지만 Shift_JIS에서도 사용하지 않는
80
,A0
,FD
~FF
에 문자가 더 추가되었다. - NTT도코모 i-mode: PC-9800 확장에서 13행만 가져 오고, 이와는 별개로 112~114행에 자체적으로 사용하는 에모지를 추가하고 있다.
- Shift_JIS가 너무 많이 쓰이다 보니까 표준안까지도 Shift_JIS 확장을 염두에 두고 문자 위치를 정하기까지 한다. JIS X 0213의 제 2면은 잘 구겨 넣으면 95~120행에 들어 가는데, 표준안에 아예 어떻게 구겨 넣는지 명세가 되어 있다(...). 물론 실질적으로는 다른 확장들이 너무 널리 쓰여서 그리 많이 쓰이진 않는다.
여기서 볼 수 있듯이, 똑같은 Shift_JIS라 하더라도 확장에 대해서는 완전히 다른 결과가 나올 수 있다.[3]
문제점[편집 | 원본 편집]
확장 영역으로 인한 호환성은 둘째치고라도, Shift_JIS는 특히 문자열 처리에 매우 취약하다. 여타 다른 멀티바이트 문자 인코딩이라고 안 그렇다는 건 아니지만 이 쪽은 그 정도가 특히 심하다. 예를 들어서:
- 문자열을 뒤에서부터나 중간에서 한 글자씩 제거하는 것이 매우 어렵다. 두번째 바이트가 ASCII랑 겹치는 경우가 있어서 그런데, 이게 안 되면 문자열을 주어진 바이트 크기 안으로 잘라서 맞추는 게 삽질이 된다.
- 비슷한 이유로 인코딩된 문자열에 오류가 있을 때 오류를 바로 잡기 어렵다. 어떤 문자가 보통의 ASCII 문자인지, 아니면 2바이트 열의 두번째 바이트만 남은 것인지 확인하기 특히 어렵다.
- 좀 더 심각한 문제로, 마이크로소프트 윈도우에서 디렉토리 구분자로 쓰이는
\
(0x5c)가 보통 문자열\
말고 바이트열 속에5C
가 들어갈 경우 단순한 바이트 비교로는 감지를 할 수 없게 된다. 일본어 윈도에서 압축한 ZIP 파일을 열어 보면 이게 뭔 소린지 알 수 있게 된다.
세번째 문제는 너무 궤멸적인 까닭에 압축 해제 소프트웨어들이 웬만해서는 ZIP 파일의 인코딩을 사용자가 선택할 수 있게 하는데 큰 역할을 했다. 어찌 보면 잘 된 걸수도 있다(...). CP949 인코딩은 여기에서 뼈저린 교훈을 얻고 좀 더 정상적인 설계를 사용하였다.
각주[편집 | 원본 편집]
- ↑ 사실 제2차세계대전 이전의 공식 문서에서는 가타카나가 현재의 히라가나의 자리를, 히라가나가 현재의 한자의 자리를 차지하고 있었으며, 1980년대까지만 해도 전산화가 필요한 곳(전보 등)에서는 가타카나가 기본으로 쓰였다. 어쩌면 JIS X 0201의 설계자들은 GB 2312 및 GB T 12345와 같이 똑같은 매핑에 히라가나와 가타카나만 다른 문자 집합을 구상했을 지도 모른다.
- ↑ 실제로는 특수 문자는 NEC 특수 문자를 기준으로, 한자는 IBM 확장 한자를 기준으로 인코딩하고 나머지는 호환을 위해서만 유지한다.
- ↑ 심지어 유니코드에 인코딩이 안 되어 있어서 유니코드 기반 글꼴로는 완벽한 지원이 불가능한 경우도 있다. MacJapanese가 그런 경우로, 맥오에스텐에 기본으로 들어 있는 ヒラギノ 계열의 글꼴이 이 이유로 일부 문자를 지원하지 않는다. 이게 무슨....