Shift_JIS

L위키, 시민들이 참여하여 가꾸는 리버럴 위키
Shift_JIS의 구조를 나타낸 이미지

마이크로소프트주식회사 아스키가 합작해서 만든 일본어 문자인코딩. JIS X 0201JIS 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 1001KS 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는 플랫폼 독립적인 상황(HTMLMIME)에서 오랫동안 널리 쓰였다. 또한 마이크로소프트는 한중일 문자 인코딩을 모두 자체적으로 재정의했음에도 불구하고 일본어 인코딩만큼은 다른 회사와 보조를 맞출 수 밖에 없었다(게다가 인코딩 설계에 결정적인 역할도 담당하지 못 했다).

구조[편집 | 원본 편집]

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 인코딩은 여기에서 뼈저린 교훈을 얻고 좀 더 정상적인 설계를 사용하였다.

각주[편집 | 원본 편집]

  1. 사실 제2차세계대전 이전의 공식 문서에서는 가타카나가 현재의 히라가나의 자리를, 히라가나가 현재의 한자의 자리를 차지하고 있었으며, 1980년대까지만 해도 전산화가 필요한 곳(전보 등)에서는 가타카나가 기본으로 쓰였다. 어쩌면 JIS X 0201의 설계자들은 GB 2312GB T 12345와 같이 똑같은 매핑에 히라가나와 가타카나만 다른 문자 집합을 구상했을 지도 모른다.
  2. 실제로는 특수 문자는 NEC 특수 문자를 기준으로, 한자는 IBM 확장 한자를 기준으로 인코딩하고 나머지는 호환을 위해서만 유지한다.
  3. 심지어 유니코드에 인코딩이 안 되어 있어서 유니코드 기반 글꼴로는 완벽한 지원이 불가능한 경우도 있다. MacJapanese가 그런 경우로, 맥오에스텐에 기본으로 들어 있는 ヒラギノ 계열의 글꼴이 이 이유로 일부 문자를 지원하지 않는다. 이게 무슨....
Copyright.svg 이 문서는 메아리 풉의 Shift_JIS 문서(저자: 강 성훈)에서 파생되었습니다.