2008년 11월 5일 수요일

hunspell 한글 검사 실험 - proof of concept

개요는 생략.

hunspell 프로그램이 한글 단어의 edit distance를 계산할 수 있으려면 내부 처리는 모두 첫가끝 코드로 바꿔야 한다. 프로그램을 바꾸기는 어려우니 첫가끝 코드로 변환하고 복원하는 간단한 필터 작성. 만만한게 파이썬에 들어 있는 unicodedata.normalize.

#!/usr/bin/env python
import unicodedata
import sys

while True:
    line = sys.stdin.readline()
    if not line:
        break
    line = unicodedata.normalize('NFC', line.decode("UTF-8")).encode("UTF-8")
    sys.stdout.write(line)
#!/usr/bin/env python
import unicodedata
import sys

while True:
    line = sys.stdin.readline()
    if not line:
        break
    line = unicodedata.normalize('NFD', line.decode("UTF-8")).encode("UTF-8")
    sys.stdout.write(line)

그리고 hunspell의 언어 추가에 필요한 두 가지 데이터, 사전과 affix 파일을 작성한다.

완전한 사전 데이터가 있을 리가 없고... 일단 마구 생각나는 단어 "가방", "발", "컴퓨터"를 입력해 본다. 이 파일은 hunspell에서 직접 읽어들이기 때문에 첫가끝으로 변환해야 하는데..  앞에서 작성한 필터로 변환한다.
3
가방/JS
발/JS
컴퓨터/JS

AFF 파일 작성, 욕심은 자제하고 조사 규칙만 입력한다. 원래는 용언의 어간과 어미를 넣어보려고 했으나.. proof of concept으로 명사 + 조사의 형태의 규칙만 만들어 본다. 받침이 있고 없고에 따라 달라지기 때문에 모음과 자음 목록을 첫가끝으로 입력해야 하는데, 좀 성가시므로 gucharmap을 이용했다.
SET UTF-8
LANG ko_KR
FLAG long

TRY ᄀᄁᄂᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ
WORDCHARS ᄀᄁᄂᄃᄄᄅᄆᄇᄈᄉᄊᄋᄌᄍᄎᄏᄐᄑ하ᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ

# 조사
SFX    JS    Y    9
SFX    JS    0    에    .
SFX    JS    0    가    [ᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ]
SFX    JS    0    이    [ᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ]
SFX    JS    0    를    [ᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ]
SFX    JS    0    을    [ᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ]
SFX    JS    0    는    [ᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵ]
SFX    JS    0    은    [ᆨᆩᆪᆫᆬᆭᆮᆯᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ]
SFX    JS    0    로    [ᅡᅢᅣᅤᅥᅦᅧᅨᅩᅪᅫᅬᅭᅮᅯᅰᅱᅲᅳᅴᅵᆯ]
SFX    JS    0    으로    [ᆨᆩᆪᆫᆬᆭᆮᆰᆱᆲᆳᆴᆵᆶᆷᆸᆹᆺᆻᆼᆽᆾᆿᇀᇁᇂ]

그리고 테스트를 위해 커맨드라인을 첫가끝으로 변환해서 hunspell에 처리한 다음 다시 음절로 바꾸는 스크립트 작성.
#!/bin/sh
echo $* | ./syl2jamo.py | hunspell -d ko_KR | ./jamo2syl.py

몇 번의 시행착오 끝에 hunspell을 이용한 초보적인 한글 맞춤법 검사 동작!
duncan:~/hacks/hunspell$ ./test.sh 가방
Hunspell 1.2.6
*
duncan:~/hacks/hunspell$ ./test.sh 가방이
Hunspell 1.2.6
+ 가방
duncan:~/hacks/hunspell$ ./test.sh 가뱅
Hunspell 1.2.6
& 가뱅 1 0: 가방

duncan:~/hacks/hunspell$ ./test.sh 따방
Hunspell 1.2.6
& 따방 1 0: 가방

duncan:~/hacks/hunspell$ ./test.sh 컴퓨터가
Hunspell 1.2.6
+ 컴퓨터

duncan:~/hacks/hunspell$ ./test.sh 컴퓨터이
Hunspell 1.2.6
& 컴퓨터이 2 0: 컴퓨터에, 컴퓨터

duncan:~/hacks/hunspell$ ./test.sh 컴퓨방
Hunspell 1.2.6
& 컴퓨방 2 0: 컴퓨터, 가방

duncan:~/hacks/hunspell$ ./test.sh 발로
Hunspell 1.2.6
+ 발

duncan:~/hacks/hunspell$ ./test.sh 발으로
Hunspell 1.2.6
& 발으로 3 0: 가방으로, 발로, 발


실제 활용할 수 있을 정도로 끌어올리기에는 할 일이 많다. 다른 프로그램과 연동을 고려하면 첫가끝 변환 코드는 실행 파일에 내장해야 한다. 또 우리말 형태론에 맞게 주의깊게 접두어/접미어 규칙이 작성되어야 한다. (복잡한 용어 어미 변화도 가능해 보인다.) 단어별로 특성이 기술된 단어 사전을 축적하는 게 가장 시간이 오래 걸리는 일이다.

하지만 hunspell로 처리할 수 있다는 건 확인할 수 있었다. 오픈오피스와 파이어폭스 사용자의 피드백을 이용할 수도 있다는 점에서 별도의 프로그램을 작성하는 것보다는 더 가능성 있는 방향으로 보인다.

2008년 11월 3일 월요일

안드로이드폰 G1의 티보이제이션

구글 그룹스에서 Q&A 중의 구글 관계자의 말에 따르면,

The G1 is aimed at end users, not system developers. For user security reasons the G1 will only accept properly signed system images. I'm not sure, in this case, who 'owns' the key, whether it is the carrier or the manufacturer, but one or both of them handle insuring system images are signed.

G1은 일반 사용자용 제품이지 시스템 개발자가 사용하는 게 아니예요. 보안때문에 G1에서는 올바르게 서명한 시스템 이미지만 받아들입니다. 이 경우에는 누가 그 키를 "소유"하는지, 즉 통신사인지 제조사인지 확신하지 못하겠군요. 어쨌든 이 둘 중의 하나 혹은 둘 모두에서 시스템 이미지의 서명을 관리합니다.

Cheers,

Justin
Android Team @ Google

이 말은 즉슨, 커널 및 시스템 프로그램들의 소스코드는 오픈되어 있으나 그 소스코드를 바꾸더라도 T-Mobile이나 HTC가 가지고 있는 디지털 키로 서명하지 않는 한 실제 장비에는 돌릴 수 없다는 뜻이다. 전형적인 티보이제이션이다. G1은 기대와는 달리 오픈 플랫폼이 아니다.

구글 혹은 T-모바일쪽의 이러한 결정이 사악하느냐 (be evil) 아니냐를 떠나서, 컴파일해 봤자 실제 장비에서 돌릴 수 없는 소스코드라면, 안드로이드의 소스 코드를 오픈한 게 과연 무슨 의미가 있는 걸까? 휴대폰 개발사에 소속되어 개발용 폰을 받지 않는 한, 안드로이드의 시스템 코드 개발자들은 안드로이드 SDK에 들어 있는 에뮬레이터의 한계에 갇힐 수밖에 없다.

2008년 9월 5일 금요일

크롬에 액티브엑스라니

"액티브X와 공존 모색"…구글, 웹브라우저 시장 '초강수'

액티브엑스를 정확히 어떻게 돌리겠다고 한국의 웹 환경을 위해 액티브엑스를 지원한다는 발언을 한 건지 모르겠는데.. 어떻게 만들던 간에 32비트 x86 MS Windows 전용이 되는 걸 피할 수 없다.

지금 MS 전용 브라우저를 만들어서 MS를 넘어서 보겠다는 얘기를 하고 있는 건가? ("`크롬`은 MS 잡을 대항마" 에릭 슈미트 구글 CEO, FT와 인터뷰서 도전 시인) 아니면 악성코드의 매개체였던 기술을 구현해서 MORE SECURE한 ("Google on Google Chrome" comic book) 브라우저를 만들어내겠다는 건가?

아마도 크롬의 소스가 공개된 걸 국정원이 발견하면 보안용으로 못 쓰게 만들 것 같은데 (리눅스 보안 제품 국정원 차별 논란), 그러면 한국을 위해 closed source로 만들 지도?


2008년 8월 31일 일요일

지역화 관련 코드 표준들


ISO 639 - 언어 코드. 2글자의 알파벳 코드. 한국어는 KO. (KR이 아니다.)

ISO 639-2 - ISO 639와 마찬가지로 언어코드이지만 3글자 코드이다. 한국어는 KOR이다. tut(Altaic), ine(Indo-European)처럼 특정 언어가 아닌 언어군을 가리키는 코드까지 포함되어 있고, tlh(Klingon, 스타트렉의 외계인이 쓰는 언어)같은 인공어도 들어 있고, 고대와 현대의 언어를 구분해 놓는 등 좀 의문이 드는 코드가 다수 들어 있다. 가장 문제라고 할 수 있는 부분이, terminology use와 bibliography use에 사용하는 코드를 별도로 구분해 놓아 23개의 언어에 대해서 T 코드와 B 코드가 다르다. (독일어의 경우 T 코드는 deu, B 코드는 ger.) B 코드는 당시의 도서관 시스템들이 기존에 분류 기준으로 사용하고 있는 코드를 그대로 수용한 결과이다. 마이크로소프트가 OS에 사용하는 언어 코드가 3글자라서 ISO 639-2가 아닌가 오해하곤 하지만 MS가 임의로 만든 코드이다.

ISO 639-3 - 또 다른 언어 코드. 역시 3글자 코드이고 639-2보다 훨씬 더 확장되었다. 한국어는 마찬가지로 KOR. 하지만 문제의 B/T 코드 구분은 없어지고 T 코드만 사용한다, 언어군을 가리키는 코드도 없어졌다. (클링온은 남아 있음.)

ISO 3166 - 국가 코드. 주권국이 아닌 식민지, 자치 지역, 남극같은 곳에도 코드가 있기도 하다. alpha-2 코드는 대한민국이 KR. (KO가 아니다.) 국가 체제는 어느날 갑자기 분리독립을 하거나 통일/병합되거나 개명하거나 하는 식으로 바뀔 수 있는 것이라 끊임없이 개정되어 왔다.

ISO 3166 alpha-3 - ISO 3166의 subset으로 3글자 코드이고 대한민국은 KOR. 국가 대표 선수들의 이름표도 그렇고, 유닉스/리눅스 L10N에 관련된 사람이 아니라면 2글자 코드보다는 3글자 코드를 일상생활에서 더 많이 볼 수 있다.

ISO 3166 numeric - ISO 3166의 subset으로 3글자의 숫자 코드이다. 대한민국은 410.

ISO 3166-2 - 국가 코드가 아니라 세부 지역 코드이다. ISO 3166 코드 뒤에 세부 지역 코드를 대시로 연결한다. 알파벳이나 혹은 숫자 1글자에서 3글자 사이의 코드로 표기한다. 미국의 주 따위가 대표적으로 미국은 US-TX(텍사스)처럼 우편 약자를 사용한다. 한국에 해당하는 코드는 ISO 3166-2:KR subset에 정의되어 있는데 광역 자치단체별로 구분되어 있고 세부 지역코드는 숫자를 사용한다. 서울은 KR-11, 대전은 KR-30. 이 부분도 각 지역의 행정 체계의 변화에 따라 끊임없이 개정된다.

ISO 15924 - 문자 (script) 코드. 4글자의 알파벳 혹은 숫자 코드이다. 라틴 문자는 통틀어서 Latn이고 한자는 공통으로 Hani가 있는 반면에 중국어 간체는 Hans 번체는 Hant로 구분되어 있다. 한글은 문자코드는 Hang, 숫자코드는 286이다. Hang의 alias로 Kore/287도 있다.

ISO 4217 - 화폐 코드. 흔히 국제 환율 얘기할 때도 많이 쓰는 코드이다. 원화는 KRW.

RFC 4646 - HTML/XML에 사용하는 언어 표기 방법. xml:lang 따위가 대표적이다. ISO 639, ISO 15924, ISO 3166 문자 코드를 순서대로 대시 기호로 연결한다. ISO 639는 소문자, ISO 3166은 대문자로 쓰고, ISO 15924는 첫 글자만 대문자로 쓴다. ISO 639 뒤의 코드를 생략할 수 있고, 중간의 ISO 15924 코드만 생략할 수도 있다. 즉 한국어라면 "ko", "ko-KR", "ko-Hang-KR", "kor", "kor-KOR", "kor-Hang-KOR" 따위로 쓸 수 있다.


2008년 7월 5일 토요일

우분투 런치패드 번역의 BSD 라이센스 전환의 문제

최근 우분투 런치패드는 런치패드에 들어 있는 번역문에 대해 BSD 라이센스로 확인하는 작업을 하고 있다. 일정은 없지만 동의하지 않은 번역문은 런치패드 시스템에서 지워질 예정이다.

이러한 조치는 런치패드의 번역문들이 라이센스를 명확히 하지 않는다는 비판과 더불어, 번역문을 여러 프로그램 사이에 공유할 때 생기는 라이센스 문제에 대한 해결책으로 보인다. (예를 들어 GPL 프로그램의 번역문을 LGPL 프로그램에 사용하는 경우처럼.)

하지만 왜 하필 BSD이며, 왜 BSD가 아니면 시스템에서 지운다는 걸까?

첫째로 과연 GPL 소프트웨어의 번역을 BSD로 하는 게 가능한 것인가 의문을 갖게한다. 원문은 GPL 라이센스로 배포되는 프로그램의 소스코드에서 xgettext 프로그램을 통해 추출한 것이고 번역문은 파생 작업이라고밖에 할 수 없다. GPL 코드에서 추출한 템플릿을 번역한 번역문의 라이센스를 BSD로 한다는 게 가능한 것일까?

또 실제적으로 런치패드의 온라인 번역 시스템이 훌륭하긴 하지만 여전히 훨씬 더 많은 번역문들이 이 시스템 밖에서 만들어져서 런치패드 시스템으로 import되고 있다. 런치패드에 들어 있는 번역문의 대다수는 런치패드에서 시작한 번역문이 아니라 외부에서 import한 번역문을 보완한 정도이고 이렇게 GPL 번역문을 고쳐서 만들어진 결과물을 BSD 라이센스라고 할 수는 없다. 이러한 모든 번역을 지우고 런치패드 내부에서 scratch부터 시작할 것인지?

그리고 GPL은 GPL의 가치가 있다. 나는 내가 번역한 번역문이 해당 소프트웨어의 라이센스를 따르게 할 뿐, 일부러 번역문에 BSD 라이센스를 사용할 생각은 전혀 없다. GPL의 파생작업에 대한 라이센스 조항을 좋아하든 싫어하든 이 GPL 조항은 자유소프트웨어 발전에 대단히 큰 역할을 했다. 런치패드 시스템에서 사용하려고, 호환성때문에 GPL이었을 때의 장점을 버리고 BSD를 택한다는 건 받아들이기 힘들다.

몇몇 언어의 그놈/데비안/KDE 번역 팀들은 런치패드 시스템의 편리함때문에 공식적인 번역 도구로 사용하고 있다. (한국어 번역팀은 아님.) 런치패드의 이러한 조치는 이 팀들이 계속 런치패드에서 작업해야 하는지 고민하게 만들었다. 번역문 사이의 호환성이 문제라면 좀 수고를 하더라도 라이센스 호환성 문제를 처리하도록 시스템을 구현할 수도 있지 않을까? 왜 BSD로 통일해야 하며 그게 아니면 시스템에서 지워야 할까? 이러한 결정은 지금까지 훌륭히 번역 작업을 해 온 런치패드의 발목을 잡게 될 것이다.


2008년 7월 2일 수요일

전자정부를 통한 증명 문서의 인터넷 출력

2008년 현재 대한민국전자정부의 기능을 이용해 인터넷으로 발급할 수 있는 문서는 주민등록등본, 공시지가확인서, 등기부등본, 소득증명 등 수십종에 이른다. 수년 전에 연말정산때문에 이 기능을 처음 이용해 봤을 때 어떻게 내 프린터에서 공공문서를 인쇄하는 게 가능한 건가 몹시 의심스러웠다. 근본적으로 이렇게 출력된 문서가 올바르다고 보장할 방법이 없기 때문이다. 등기부등본과 같이 서류의 목적이 열람용일 경우에는 문제가 되지 않지만, 일부 증명 용도의 서류도 인터넷으로 발급할 수 있다.

연말정산을 위해 내 프린터에서 주민등록등본을 출력했을 때, 발급자인 정부나 수신자인 국세청은 정말 위변조된 문서가 아니라고 안심할 수 있을까? 국세청은 그 문서 내용을 그대로 믿고 그 종이에 쓰여 있는 가족관계에 따라 내 세금공제를 처리해도 되는 걸까?

실제로 이 서비스는 논란이 많았고, 2005년에 위조 가능성이 제기되어 일시적으로 중지되기도 했고, 업데이트될 때마다 프린터가 지원에서 빠지기도 하고 가상머신에서 이용이 금지되기도 하고 이용자들의 불평이 쏟아졌다.

종이가 증명서가 되려면

"등본"이라는 말은 말 그대로 있는 보관되어 있는 서류와 동일한 문서를 뜻한다. 주민등록이 전산화 되기 전에는 그 주민등록 문서가 보관되어 있는 동사무소에서 신청을 하면 동사무소 직원이 서류 창고에서 해당 문서를 찾아서 복사한 다음 동사무소 직인을 찍어서 발급해 주었고 그게 "등본"이었다. 직인은 실제 문서와 동일하다는 보증이었다. 내 프린터로 인쇄하더라도 주민등록등본이 실제 정부 전산망에 기재된 내용과 동일하다는 걸 보장할 수 있는 걸까?

말많은 키보드 보안 기능과 마찬가지로 전자정부 사이트는 이렇게 인쇄한 문서가 올바르다는 보장을 클라이언트 컨트롤을 통해 하고 있다. 액티브엑스 컨트롤로 가능한 프린터의 종류를 제한하고 있다. 프린터에 보안 기능이 있어야 이용할 수 있다고 말하는 사람들이 있지만, 실제 지원하는 프린터들을 보면 보안 기능같은 건 본적이 없는 프린터들도 사용할 수 있는 걸 보면 프린터의 기능과는 상관이 없다. (시중에 나와 있는 일부 프린터에서 구현하고 있는 보안 기능은 전자정부 웹사이트가 인쇄된 문서를 인증할 수 있는 종류의 인증용 보안 기능이 아니라, 인쇄 데이터 전송의 암호화, 인쇄 작업별로 암호 지정과 같은 보안이다.)

이러한 클라이언트 컨트롤 접근 방법때문에 윈도우즈 외에 다른 OS를 지원하지 않는다거나, 시스템 의존적인 버그가 나타나거나, 개발 비용이 높아진다거나 하는 부작용이 나타난 건 물론이다.

내 프린터에서 인쇄한 종이를 증명서로 만드는 방법같은 건 없다. 왜냐하면 컴퓨터는 사용자의 것이지 전자정부 웹사이트가 마음대로 해라 마라 할 수 있는 게 아니기 때문이다. 프린터에 보낼 이미지 데이터는 결국 컴퓨터의 어딘가에서 로우 데이터로 흘러다니게 마련이고 내부에서 나름대로 암호화하고 하더라도 결국 프린터로 그 데이터를 보내야 한다. 전자정부 사이트는 일단 이용자가 소유한 컴퓨터를 서비스 제공자 마음대로 조작할 수 없다는 걸 인정해야 한다. 이 사실을 인정하지 못하고 사용자에게 배포하는 클라이언트 소프트웨어를 조작하는 방법으로 문제를 해결하려고 하면 상황이 지금과 같이 복잡해 진다.


대안 - 종이가 아닌 데이터를 증명용으로 쓰자!

인쇄한 종이 그 자체가 증명 자격을 가지지 않도록 해야 한다.

단 출력한 내용이 사실 여부를 조회할 수 있도록 하는 티켓 역할을 하도록 만들 수는 있을 것이다. 예를 들어, 회사의 복지제도를 이용하기 위해 내 가족관계가 이러하다는 걸 증명하려면 주민등록초본이 필요할 것이고, 초본의 역할은 제 3자에게 나의 가족관계를 증명하는 것이다. 지금의 초본은 출력한 서류 그 자체가 증명 자격을 갖도록 되어 있지만, 이제 그런 공식적인 증명 자격을 없애고 전자정부에 가족관계를 조회할 수 있는 one-time pass 역할만 하게 만드는 것이다. 그러면 서류의 목적도 달성할 수 있고 사용자의 프린터를 컨트롤할 필요도 없다.

현재도인터넷에서 출력한 문서는 고유번호와 바코드가 기재되어 있고 진위여부를 확인할 수 있다. 기술적으로는 아무런 문제가 없다. 단지 출력한 서류 그 자체가 증명 서류가 아니고 one-time pass일 뿐이라는 걸 인정하면서 기존의 업무체계가 동작할 수 있느냐가 관건이다.



2008년 6월 12일 목요일

2008년 6월 10일 청와대 홈페이지

며칠 더 유지됐었다면 아마 구글에서 피싱 사이트로 분류할 수도 있었을 텐데.

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko"><head><title>청와대에 오신 것을 환영합니다.</title>

   
    <meta http-equiv="content-type" content="text/html; charset=euc-kr"></head><body>
    <img src="index.jpg" border="0" height="934" width="1259">
</body></html>

index.jpg 파일은 청와대 사이트를 캡쳐해 놓은 그림이다.

사이트 폭주가 발생하면 무언가 대응을 하긴 해야 한다. 효율 개선, 용량 늘이기, 악의적인 연결을 차단하기, 다른 방법이 없다면 임시 폐쇄를 결정할 수도 있는 일이다. 하지만 조금이라도 의식이 박혀 있다면 이렇게 가짜 이미지를 뿌리는 짓은 하지 않는다.