기본 콘텐츠로 건너뛰기

Unicode 2.0 에서 한글의 이해

요즘 SNS이나 SNG등등 기계적으로 문장을 생성하는 프로그램들이 넘쳐나는 시대에 의외로 한글처리를 제대로는 프로그램들이 드물구나 하는 생각에 간단한 한글 자소 분석기를 만들어보았다.
링크는 이쪽(http://jsbin.com/ofoqal/10/edit)

애초에 만든 목적은 다음과 같다.
조사처리(은/는, 이/가, 을/를 등등)를 위해 단어의 마지막 글자의 종성을 조사하기 위함인데 예문을 들어보자면

"준기는 강남에서 사진을 찍었다."
"예슬은 홍대에서 식사를 했다."
"슬기가 대화방에서 나갔습니다."

"준기님은 강남에서 사진님을 찍으셨습니다 고갱님" 이라고 말하면 할말 없다.

한국식 소프트웨어(꼭 소프트웨어가 아니더라도)의 특징이자 장점이 무엇이냐라고 물으면
귀찮을 정도로 깨알같은 디테일이라고 대답할텐데 한글 기계화 작업에 대한 중요성은 프로그램을 만드는 사람들에게도 별로 중요하게 다가오지 않나보다.

에또 사설이 길었다.
한때 우리는 한글코드체계의 비표준 숲속에서 너무도 괴로운 나날들을 보낸 역사가 있다.
KSC5601부터 시작해서 Microsoft통합형한글을 지나 Unicode 2.0의 시대가 왔다.

개인적으로 UTF-8을 사용하지 않고 EUC-KR이나 CP949를 쓰는 제품이나 서비스의 업체의 대표/관계자에게 1억 미만의 벌금 혹은 3년 이하의 금고형의 실형을 내려줬으면 할 정도로 너무나 많은 사람들을 불행하게 하고 막대한 비용을 지출한 악의 근원이라고 생각한다.

하지만 광명이 왔다.
기계적으로 납득이 가능한 검색 및 정렬이 용이한 Unicode 의 시대가 열렸단 말이다.
지금 당신이 복사해서 붙이고 있는 팁들 보다 훨씬 쉽고 명쾌하니 다음 그림을 한번 보자.
어떤가?
무쟈게 쉽지 않은가?

현대 한글은 초성 19자, 중성 21자, 종성 27자로. 총 19 x 21 x 28 (종성없음 포함) = 11172자 되겠습니다.
빈값이 없이 빽빽하게 들어찼단 말이다.

초성은 ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ (19자)
중성은 ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ(21자)
종성은 (없음)ㄱㄲㄳㄴㄵㄶㄷㄹㄺㄻㄼㄽㄾㄿㅀㅁㅂㅄㅅㅆㅇㅈㅊㅋㅌㅍㅎ(28자)

이것 밖에 없다.
교ㅑ
  ㄱ
이런거 안된단 말이다.

자 지금 당장 javascript console을 열고 이렇게 쳐보자.
저 대로라면 한글의 가장 첫번째 글자는 무엇일까?
당연 '가' 되겠다.

> '가'.charCodeAt().toString(16).toUpperCase()
"AC00"

그렇다. 이게 시작이다. 0xAC00. 10진수로 44032.
그럼 '문' 이건 어떻게 될까?
초성인 'ㅁ'이 6번째
중성인 'ㅜ'이 13번째
종성인 'ㄴ'이 4번째 되시겠다.
44032+6*21*28+13*28+4 = 47928 인거다.

> String.fromCharCode('가'.charCodeAt() + 6*21*28 + 13*28 + 4 )
"문"

아름답다. 아름다와.
같은 방법으로 초중종을 분리해보자.

47928(문)-44032(가)=3896 이니
3896 을 기준으로

초성 Math.floor(3896/21/28) = 6(ㅁ)
중성 Math.floor((3896 - 6*21*28)/28)=Math.floor(3896/28-6*21) = 13(ㅜ)
종성 3896 % 28 = 4(ㄴ)

이게 전부다. 코드도 그냥 이것대로 한거고.
애초에 초반에 말했던 을/를, 이/가 등의 조사를 구분하는 함수를 만든다면 어떨까?

var hasJongsung = function(word) {
  return !!(word && word[word.length -1].charCodeAt()>=0xAC00 && word[word.length -1].charCodeAt()<=0xD7A3 && (word[word.length -1].charCodeAt()-0xAC00)%28);
};

그저 이렇게 한 줄 코드로 해결할 수 있다.
종성이 있을 경우 true를
종성이 없거나 한글이 아닐 경우 false를 반환한다.

지금 만들고 있는 프로그램에도 한번 적용해보자. 고기덕후세종대왕느님들이 고생해서 만든 글인데 아깝지 않은가?

댓글

이 블로그의 인기 게시물

세상 간단한 https(+secured websocket): Caddy

nginx, apache2 같은 걸로 매번 certbot 연동을 통해 https 하는게 지겨워서 알아보니 Caddy라는게 있더라. 설치법은 강하게 크기 위해 알아서 해본다. # cat /etc/caddy/Caddyfile your.shitty.site:8123 {   proxy / localhost:9123 {     websocket     transparent   } } 이건 외부에서 8123으로 들어오는 걸 내부적으로 9123로 맞춰서 https 맞춰주는 reverse proxy. 만일 port를 생략하면 # cat /etc/caddy/Caddyfile your.shitty.site {   proxy / localhost:9123 {     websocket     transparent   } } 기본포트인 443으로 되어 https://your.shitty.site 로 접속이 된다. 요새 말썽이던 cloudflare 버리고 netlify domain이랑 caddy를 쓰니까 앓던 이가 빠진 느낌. 이 조합은 당분간 계속 써야겠다 싶다.

저지연 오디오 생성 LLVC 사용기

https://github.com/KoeAI/LLVC 써봄 CUDA 11.8 버전 쓰고 있어 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 VC 없어서 설치 https://wikidocs.net/168848 참조 FAIRSEQ 관련 오류 https://github.com/facebookresearch/fairseq/issues/2908 pip install editdistance  설치 No CUDA runtime is found, using CUDA_HOME='C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.8' 오류 멀쩡하게 있는데 안됨. pip install torch==2.1.0+cu118 torchvision==0.16.0+cu118 torchaudio==2.1.0+cu118 --extra-index-url https://download.pytorch.org/whl/cu118 다시 설치 set DISTUTILS_USE_SDK=1 이게 문젠가 설정하고 재도전 Using cached ruamel.yaml.clib-0.2.8-cp311-cp311-win_amd64.whl (118 kB) Building wheels for collected packages: fairseq   Building wheel for fairseq (pyproject.toml) ... error   error: subprocess-exited-with-error   × Building wheel for fairseq (pyproject.toml) did not run successfully.   │ exit code: 1   ╰─> [1829 lines of output]       No CUDA runtime is found, usi...