(20120612) 스크랩 한글인코딩이야기 (ASCII, 완성형, 조합형, EUCKR, CP949, UTF-8)» Think Like Feynman 컴퓨터세상의문자세계는유니코드강림 (?) 전세상과유니코드강림후세상이존재한다. 물론우리는유니코드강림후세상에살고있다. 하지만많은일이그렇듯이현재를잘알기위해서는과거를잘알아야한다. 특히나과거의유산속에서같이살고있는경우라면두말할나위가없다. 한글인코딩의전반부에는 ASCII, 완성형, 조합형에대해서먼저알아보자. 1) ASCII 한글인코딩이야기를하기전에 ASCII 이야기부터해보자. ASCII는꽤나추상적이고철학적인 글자 라는개념을컴퓨터로표현, 저장하기위한방법이다. 다시말해글자하나하나를숫자와짝지어둔일종의표라는이야기다. A는 65라고컴퓨터에서저장하고, B는 66이라고저장하자 이런식으로미리약속을한것이다. 그럼 ASCII 코드는몇비트를사용하는코드체계인가? 7비트다. 알파벳과기타필요한문자들을표현하는데 128글자 (2^7) 면충분했기때문이다. 하지만대부분컴퓨터는기본저장단위로 8비트를사용한다. 이남는 1비트때문에혼돈과가능성의시대가열린다. 2) 코드페이지 약간골치가아프지만잠시비트단위이야기를해보자. 앞에서도이야기했듯이우리는일반적으로 1바이트 =8비트인컴퓨터를쓰기때문에 ASCII 코드를사용하면 1 비트가남는다 ( 물론 1바이트는 8비트가아닌컴퓨터도있다 ). 다시말해 8비트체계에서 ASCII 코드는 00000000(0)~01111111(127) 까지만쓰기때문에 10000000(128)~11111111(255) 까지의영역이남는다는뜻이다. ASCII 코드에포함되지않은글자를사용하는나라들이이영역에자신들의글자를채워넣기시작했다. 문제는이런과정이통제된방식이아닌각나라들의독자적인방법으로동시에진행됐다는점이다. 0~127 까지의영역은이미표준으로자리잡은 ASCII 코드방식으로해석을하면문제가없었지만, 128 이상의영역은각나라마다할당된문자들이달랐기때문에이영역의수를문자로바꾸기위해서는또다른방법이필요했다. 이해석방법이코드페이지다. 어떤코드 ( 숫자 ) 가주어졌을때현재코드페이지가 737 ( 그리스 ) 라면 127이하의글자는기존의 ASCII 방식으로해석하고, 128
방식은그리스문자를위한방식으로해석해야한다. 문자와코드사이의관계가 ASCII 만존재할때보다복잡해졌지만, 이문제는멀티바이트코드가등장하면서 더욱악화된다. 3) 멀티바이트코드 안타깝게도한글을포함해서몇몇글자체계들 ( 주로중국, 일본, 한국을통틀어서 CJK라고부른다 ) 은기존의 8비트코드체계로는모든글자를표현할수가없었다. 하지만한글자를표현하기위해서 2바이트를사용한다면 2^16=65536글자라는넓은공간을사용할수있고, 한글역시모두표현할수가있다. 이런생각으로등장한것이멀티바이트코드다 ( 한글표현을위한멀티바이트방식에는 2바이트가아닌 3바이트방식등도있지만이글에서는가장일반적인 2바이트방식만고려하자 ). 어떤바이트의최상위바이트가 0이라면, 즉 127이하라면기존의 ASCII 코드로해석하면된다. 대신그바이트의최상위바이트가 1이라면, 즉 128이상이라면이바이트와바로다음바이트는한글을의미한다. 이제한글이사용할수있는범위는 2바이트이므로 128~65535까지의숫자는한글로해석하면된다. 하지만안타깝게도여기에서이야기가끝나지않는다. 4) 완성형, 조합형 128~65535라는영역이한글을위한공간으로주어졌지만이곳에한글을어떻게할당하느냐는문제가남았다. 여기에서대해서두가지의견이존재했다. 첫번째는한글한글자한글자를독립된개념으로생각하고각글자에코드를부여하는의견이다. 예를들면 가 는 128, 나 는 129, 다 는 130을할당하는방식이다. 두번째는한글의창제원리인초성, 중성, 종성의개념을살려서한글이사용할수있는 15 비트 ( 최상위 1비트는사용할수없다 ) 를세개로쪼개서초성, 중성, 종성에게각각 5비트를할당하자는의견이다. 즉, 1xxxxxyyyyyzzzzz 라는비트구조가된다. 예를들어초성 ㄱ 이 1, 중성 ㅓ 가 3, 종성 ㄱ 이 1이라면 걱 은 1000010001100001 으로표현된다. 전자를한글한글자한글자를 완성 된글자로본다는의미에서 완성형 이라고하고, 후자를한글한글자한글자는초성, 중성, 종성이 조합 된결과라는의미에서 조합형 이라고한다. 완성형과조합형은각자의장단점을가지고꽤나치열했던코드논쟁을일으켰다. 조합형은한글의창제원리를고스란히담고있고, 조합이라는방식덕에모든한글을표현할수있다는장점이있다. 하지만코드를글자로변환하기위해서는 2바이트를비트단위로쪼개서해석을해야하기때문에처리상의부담이있었다. 반면완성형은숫자가글자를그대로의미하기때문에비트단위해석의부담은없었지만한글의창제원리를무시하고마치한글을한자처럼취급한다는단점이있었다. 오히려완성형을자소단위로쪼개기위해서는추가적인해석부담이있다. 더군다나뒤에더이야기가되겠지만실제로는완성형에서한글을위해할당된영역이
128~65535 가아닌제한된영역이기때문에모든한글을표현하지못하는문제가 발생했다. 당시전산계에있던사람들사이에서는조합형의우월성에많은점수를주었지만, 완성형방식이표준으로채택되면서꽤나시끄러웠던한글코드논란은사그라들 었다. 5) EUCKR 안타깝지만조합형은표준으로채택되지않았기때문에이제는완성형에대해서만이야기하자. 표준완성형인코딩방식의다른이름은 EUCKR이다. EUCKR은 KS X 1003과 KS X 1001으로구성된다. KS X 1003은역슬래쉬대신에원화표시를사용한다면점을제외하면아스키코드의문자들과같다. KS X 1001은한글과그림문자, 한자등을포함한다. EUCKR은 127이하에는 KS X 1003을, 128이상에는 KS X 1001을할당했다. 128이상이라고하지만실제로 EUCKR이사용한공간은상위바이트 161~254, 하위바이트 161~254뿐이다. 더구나 KS X 1001에는한글외에도그림문자와한자등의글자가많기때문에그렇지않아도작은이영역에들어가지못한한글이생겼다. 바로 똠 이나 뷁 등이다. PC 통신세대라면어떤게시물들의글자가보이지않았던경험이있을것이다. 그글자들이바로 KS X 1001, 그리고 EUCKR에서제외된글자들이다. 6) CP949 자주사용되지않는몇몇글자들을 EUCKR에서사용할수없다는점이어떤사람들에게는별문제가아니었지만어떤사람들에게는큰문제였다. 예를들어고어를많이사용하는국어학자라거나, 채팅이나소설에서독특한표현 (?) 을사용하는사람들에게 EUCKR은족쇄나마찬가지였다. 이때등장한것이마이크로소프트의 CP949 즉, 코드페이지 949이다. CP949는마이크로소프트가 KS X 1001에없는한글 8822글자를추가해서 EUCKR을확장한완성형인코딩방식이다. 128이상의영역중 EUCKR이사용하지않던영역에이 8822글자를할당했다. 그래서 CP949는확장완성형또는통합형한글코드라고도불리운다. 마이크로소프트에서는 CP949를 ks_c_5601-1987이라고도부른다. 코드페이지 라는명칭에서도알수있듯이 949는앞에서이야기한한글해석을위한코드페이지번호였다. 즉, 현재코드페이지가 949라면 128이상의바이트를이러이러한방식으로해석하라는약속이었다. 하지만지금은 CP949는 EUCKR의확장형인한글을위한인코딩방식을지칭하는이름이다. 7) EUCKR VS CP949
EUCKR과 CP949는혼동되는경우가있지만둘은엄연히다른인코딩방식이다. 둘이혼동되는이유는둘다완성형방식이고 CP949가 EUCKR을완전히포함하기때문일것이다. 우리가윈도에서사용하는한글은 EUCKR아닌 CP949로표현된다 ( 물론윈도는내부적으로는예전부터유니코드를사용하고있다 ). 윈도메모장에서 똠방각하 를작성한후특별한과정없이텍스트파일로저장할수가있다. 윈도가 CP949를사용하기때문이다. 정리를해보자. 유니코드가강림하기전세상에서글자를표현하기위한코드는 127이하의영역과 128이상의영역이있었다. 128이상의영역은각나라의언어별로채워졌고, 한글을비롯한몇몇글자체계에서는 2바이트이상을사용했다. 이 128이상영역의글자를해석하는방식에대한약속이코드페이지이다. 128이상영역에한글 ( 을비릇한그림문자, 한자 ) 을할당하기위해서제안된방식으로완성형, 조합형이있었고완성형이표준으로채택됐다. 완성형의표준방식은 EUCKR이었고, EUCKR은모든한글을표현하지못했다. 마이크로소프트에서 EUCKR에포함되지않은한글 8822자를 EUCKR이사용하지않던영역에할당했고이를확장완성형또는 CP949라고부른다. 글이꽤길어졌다. 다음에는유니코드강림이후의세계. 유니코드, UTF-8 등에대 해서알아보자. http://heyjimin.tistory.com/entry/%ed%95%9c%ea%b8%80- %EC%9D%B8%EC%BD%94%EB%94%A9- %EC%9D%B4%EC%95%BC%EA%B8%B0-2- %EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C-UCS-2-UTF-8-UTF-16 [1] 조합형, 완성형에대한이야기 [2] 에이어서이번에는유니코드에대한이야기를해 보자. (1) 유니코드 전에이야기한것처럼유니코드가등장하기전에는각각의글자체계를표현하기위한인코딩방식이각각존재했다. 127이하의영역은통일되있었지만, 128이상의영역은통일된방식이없이각자의글자체계를표현하기위해서사용됐기때문이다. 128이상의영역을해석하는방법에대한약속중하나가코드페이지라는개념이었다. 하지만인터넷의보급과함께다국어지원에대한필요성이커지면서기존체계에문제점이생겼다. 동일한프로그램의한국어버전, 중국어버전, 일본어버전을개발한다고하면, 각언어로작성된문장들을물론이고, 각언어에맞는인코딩방식까지작성해야했다. 또다른문제는각언어를동시에표현할방법이없다는점이다. 같은바이트배열이라도각인코딩방식에따라해당하는글자가다르기때문이다 ( 코드페이지를전환하는수밖에없다 ).
이런두가지문제를해결하기위해서세상의모든글자를하나의체계로표현하기위해서등장한것이유니코드다. 간단히생각하면유니코드는세계에존재하는모든글자를모은후에이글자들에코드를부여한것이다 ( 실제로는이렇게단순하지는않지만우리의논의를위해서는이정도의개념이면충분하다 ). 한글의완성형방식을생각하면쉽다. 다만대상이한글이아니라전세계의모든글자일뿐이다. 한글완성형에서는기존의아스키코드는 127이하에할당되고, 추가적인부분은최대 2바이트의 128이상에할당됐다. 그렇다면유니코드는어떤가? 유니코드는약간다른개념이등장한다. 유니코드의각글자는 코드포인트 라는숫자 ( 현재까지는 21비트이지만앞으로계속확장될것이다 ) 에대응된다. 예를들어 A 는 U+41 에대응한다. 여기에서 U+ 는이숫자가코드포인트라는의미이다. 코드포인트는어디까지나추상적인개념일뿐실제로코드포인트가메모리나디스크에서표현되는방식은따로있다. 그리고이런방식이바로 UTF-8이나 UTF-16이니하는인코딩방식이다. (2) UCS-2 유니코드에대한가장흔한오해중의하나는 유니코드는 2바이트체계이고 65,536글자를표현할수있다 라는점이다. 아마이오해는초창기의유니코드방식중하나인 UCS-2때문에생긴듯하다. UCS-2는유니코드의코드포인트를 2바이트로인코딩한다. UCS-2에서문제가되는것은바이트순서 (Byte order), 또는 Endian이다. A 를 00 48 으로표현할것이가, 48 00 으로표현할것인가? Big Endian을사용하는 CPU도있고 Little Endian을사용하는 CPU도있기때문에, 효율성을위해서 UCS-2의 Endian을강제하기보다는각각의시스템에이를맡기고, 대신문자열이어떤 Endian방식을사용하는지명기하도록하는방식을선택했다. 이것이 Byte Order Mark, 즉 BOM이다. UCS-2 인코딩을사용하는문자열은실제문자들이시작하기전에, 즉문자열의처음에 BOM을추가해야한다. BOM은 FE FF 또는 FF FE 라는 2바이트다. UCS-2 인코딩방식의문자열을읽을때처음 2바이트가 FE FF인지 FE FF인지에따라나머지부분을해석하는방식을다르게하면된다. FE FF라면 A 가 00 48이고 FF FE라면 A 가 48 00 으로저장됐다고생각하면된다. BOM의등장만해도문제가복잡한데, 더심각한문제는모든 UCS-2 방식의문자열들이 BOM을달고있지는않다는점이다. 동일한시스템에서만문자열을주고받는다면문제가없지만다른바이트순서를사용하는시스템간에문자열을주고받을때는분명히문제가된다. 이보다더심각한 UCS-2 의문제는 UCS-2 가 2 바이트를사용하기때문에표현할수 있는글자의한계가 65,536 글자라는점이다. 유니코드에정의된문자는이이상 ( 현 재 21 비트 ) 이다.
(3) UTF-16 이문제를해결하기위해서등장한것이 UTF-16이다. UTF-16에는 surrogate라는개념이등장한다. surrogate는 0xD800-0xDBFF 영역의 high surrogate와 0xDC00-0xDFF 영역의 low surrogate로나뉘고이두영역을조합해서하나의문자 ( 코드포인트 ) 를만든다. surrogate를사용하면 0 010000에서 0x10FFFF사이의공간을사용할수있다 ( 현재까지유니코드의모든문자를표현할수있는공간이다 ). 기본적인인코딩방식은다음과같다. 코드포인트 A가존재한다면 A에서 0 010000을뺀다. 이값은 0 00에서 0xFFFFF사이의값, 즉 20비트이다. 그리고이 20비트를 xxxxxxxxxxyyyyyyyyyy 의두영역으로나눈후, 110110xxxxxxxxxx 110111yyyyyyyyyy 으로인코딩한다. 참고로윈도에서유니코드라고이야기하는것은 UTF-16을이야기한다. 메모장을열어서파일저장하기대화상자를보면인코딩항목을볼수있는데 ANSI는기존의코드페이지방식 ( 한글의경우는 CP949 인코딩 ), 유니코드는 Little Endian UTF-16, 유니코드 (big endian) 은 Big Endian UTF-16, UTF-8은 UTF-8방식을뜻한다. (4) UTF-8 UCS-2와 UTF-16의문제점은지나치게많은공간이필요하다는점과기존의 ASCII 체계와호환성이없다는점이다. 첫번째문제는컴퓨터상에존재하는많은글자들이기존에는 1바이트로표현할수있는글자들인데이글자들을위해서 2바이트이상을사용한다는것은너무낭비라는지적이다. 두번째문제는 UCS-2나 UTF-16과호환성을위해서는기존의문서들을모두변환해야하는데이역시문제라는지적이다. 이두가지문제를동시에해결하는인코딩방식이 UTF-8이다. UTF-8 은현재유니코드표현에필요한 21 비트를 1~4 바이트에걸쳐서나누어서표 현한다. 다른말로하자면 UTF-8 은 1 바이트가될수도있고, 2 바이트가될수도있 고, 3 바이트가될수도있고, 4 바이트가될수도있다는뜻이다. 기존의 ASCII 영역에있던글자들, 즉 7 비트만필요한글자들 ( 코드포인트로는 00000 00000000 0xxxxxxx) 은 1 바이트인 0xxxxxxx 으로표현된다. 7 비트이상이필요한글자들은차근차근바이트수를늘려간다. 코드포인트 00000 00000yyy yyxxxxxxxx 의글자들은 110yyyyy 10xxxxxx 으로,
코드포인트 00000 zzzzyyyy yyxxxxxxxx 의글자들은 1110zzzz 10yyyyyy 10xxxxxx 으로, 코드포인트 uuuuu zzzzyyyy yyxxxxxxxx 의글자들은 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx 으로표현된다. UTF-8 은 XML 문서를위한표준인코딩으로현재가장널리쓰이는인코딩방식이 다. 참고로 EUCKR 과 CP949 에존재하던문자들은 UTF-8 에서 1~3 바이트로표현된다. (5) 기타인코딩 이외에도 UTF-7, UTF-32 등의인코딩방식이있다. (6) 정리유니코드는전세계의모든글자를하나로표현하려는체계이다. 유니코드 의각글자는코드포인트라는숫자에대응된다. 코드포인트는추상적인개념으로 코드포인트를실제바이트형태로표현하기위해서는인코딩이필요하다. UCS-2 는코드포인트를 2 바이트로표현하는인코딩방식이다. UCS-2 의 Endian 을 명시하기위해서 BOM 이사용된다. UTF-16 은 UCS-2 의모든유니코드문자를표현할수없다는점을해결하기위해서 등장했다. UTF-16 은 surrogate 라는개념을사용해서코드포인트의영역을두곳 에분배한다. UTF-8은메모리공간을절약하고기존의 ASCII 체계와호환성을위한방식으로현재가장널리쓰이는방식이다. UTF-8은현재 21비트의코드포인트를 1~4바이트에걸쳐서표현한다. ASCII 영역의문자들은 1바이트로표현된다. ASCII 영역의글자는 ASCII와 UTF-8에서동일하게표현된다. http://heyjimin.tistory.com/entry/%ec%9e%90%ea%b8%b0%ec%86%8c%ea%b0%9c%ec%84%9c- %EA%B8%80%EC%9E%90%EC%88%98-%EC%A0%9C%ED%95%9C [3] 요즘각종기업들의공채가한창입니다. 구직자들입장에서가장신경이쓰인는부분중의하나가자기소개서가아닌가합니다. 자기소개서에쓸내용도문제지만분량도은근한압박입니다. 각회사에따라서쓸수있는분량에제한이있으니까요. 그런데이분량제한이라는것이구직자들을꽤나골치아프게합니다. 어떤곳은 몇자이내 라고제한을하는가하면, 어떤곳은 몇바이트 이내라고제한을하기때문입니다.
개인적으로가장직관적인방식은 몇자이내 방식이라고생각합니다. 한글이든, 영어든, 공백이든전부한글자로세는방법이지요. 몇바이트이내 라고표시하는곳에는조금문제가있습니다. 일반적으로한글한글자는 2바이트라는오해가있지만실제로는그렇지않습니다. 인코딩방식에따라서바이트수가달라질수있으니까요 ( 참고 [4] ). 확인해본결과대부분의지원사이트는한글한글자가 2바이트를차지했지만, N사와 D사는 3바이트를차지했습니다. 아마 N사와 D사는내부적으로 UTF8인코딩을사용하고있기때문이겠지요. 바이트방식의표기의문제는더있습니다. 예를들어 1,600 바이트이내 라고분량이지정되어있고일반적인방식인 EUC-KR, 즉한글한글자에 2바이트를차지하는방식을사용한다면몇글자를쓸수있을까요? 한글만쓴다면 800글자, 영어나공백만쓴다면 1,600자가되겠지요. 하지만우리는한글과공백을섞어서쓰기때문에계산이조금복잡합니다. 그래서지원자들은글을쓰면서틈틈히지원사이트에붙여넣기를해서글자수를확인해보거나, 바이트단위로글자수를세어주는프로그램을이용합니다. 몇자이내 와 몇바이트이내 방식보다더나쁜방법은두가지를섞어서쓰는곳입니다. 예를들어 몇자이내 라고표기를해놓고, 실제로는바이트수를세는곳이지요. 흔하지는않지만있습니다. 개발자혹은디자이너분이글자수와바이트수에대한오해가있었나봅니다. 그렇다면왜굳이직관적인글자수대신에비직관적인바이트수를사용할까요? 실제로현대적인대부분의시스템과라이브러리가유니코드를지원하지만아직많은사이트들은유니코드보다 EUC-KR을사용합니다. 첫번째이유는기존에 EUC- KR로구축된시스템과호환성을위해서입니다. 기존에구축된수많은 EUC-KR형태의데이터를 UTF-8로모두옮기는작업이간단한작업은아닙니다. 두번째는 UTF-8 로옮겨갈경우 DB 크기가한글만계산할경우 1.5 배의공간이필 요하기때문입니다. 지원서사이트같은경우는문제가덜하겠지만, 대량의데이터 를가지고있는사이트들에게는가벼운문제는아닙니다. 세번째이유는개발자의유니코드에대한인식때문일수있습니다. 실제로아직도 많은개발자분들께서유니코드에대한오해 ( 한글은 2 바이트 ) 와유니코드에서글자 의개념을잘못이해하고계십니다. 네번째는기존의관행때문일수있겠지요. 지금까지대부분의사이트가바이트방 식을사용했기때문에기존방식을유지하는것이구직자들에게혼란을덜일으킬 수있겠지요.
사소한문제라고생각할수도있지만이런부분에대한배려가구직자들에게는큰것일수도있습니다. 실제로글자수규정만보고자기소개서를작성했다가마감이임박해서막상지원사이트에붙여넣었다가분량초과로대공사 (?) 를해야했다는사례들도어렵지않게볼수있으니까요. ( 출처 ) http://heyjimin.tistory.com/entry/%ed%95%9c%ea%b8%80- %EC%9D%B8%EC%BD%94%EB%94%A9- %EC%9D%B4%EC%95%BC%EA%B8%B0-1-ASCII- %EC%99%84%EC%84%B1%ED%98%95- %EC%A1%B0%ED%95%A9%ED%98%95-EUCKR-CP949 [5] 1. http://heyjimin.tistory.com/entry/%ed%95%9c%ea%b8%80- %EC%9D%B8%EC%BD%94%EB%94%A9-%EC%9D%B4%EC%95%BC%EA%B8%B0-2- %EC%9C%A0%EB%8B%88%EC%BD%94%EB%93%9C-UCS-2-UTF-8-UTF-16 2. http://heyjimin.tistory.com/entry/%ed%95%9c%ea%b8%80- %EC%9D%B8%EC%BD%94%EB%94%A9-%EC%9D%B4%EC%95%BC%EA%B8%B0-1- ASCII-%EC%99%84%EC%84%B1%ED%98%95-%EC%A1%B0%ED%95%A9%ED%98%95- EUCKR-CP949 3. http://heyjimin.tistory.com/entry/%ec%9e%90%ea%b8%b0%ec%86%8c%ea%b0%9c%ec%84%9c- %EA%B8%80%EC%9E%90%EC%88%98-%EC%A0%9C%ED%95%9C 4. http://heyjimin.tistory.com/entry/%ed%95%9c%ea%b8%80- %EC%9D%B8%EC%BD%94%EB%94%A9-%EC%9D%B4%EC%95%BC%EA%B8%B0-1- ASCII-%EC%99%84%EC%84%B1%ED%98%95-%EC%A1%B0%ED%95%A9%ED%98%95- EUCKR-CP949 5. http://heyjimin.tistory.com/entry/%ed%95%9c%ea%b8%80- %EC%9D%B8%EC%BD%94%EB%94%A9-%EC%9D%B4%EC%95%BC%EA%B8%B0-1- ASCII-%EC%99%84%EC%84%B1%ED%98%95-%EC%A1%B0%ED%95%A9%ED%98%95- EUCKR-CP949