Unicode Normalization
__Toonman__이라는 도구를 제작 중이다.
zzoman.com 에서 만화용 플랫폼을 따로 분리하려다 어찌저찌 일이 커졌다.
이미지 파일명을 양식에 맞추어 작성하고 폴더에 넣기만하면 Blog를 운영할 수 있도록 돕는 일종의 Static Blog Generator인데, 그러려다보니 파일명을 한글같은 제3세계 언어로 작성가능해야 하고, 이게 특수한 환경에서 문제를 일으켰다.
서버에만 올라가면 한글명으로된 이미지들이 읽히지가 않아서 한동안 호스팅 업체를 괴롭혔지만, Github Page 에서도 동일한 이슈가 반복되어서 코드 자체에 문제가 있다는 걸 알았다.
문제는 OSX
웹에서 한글은 %D3%09
같은 문자가 나열되는 Unicode 형태로 치환되어 표현되는데, 브라우저 URL에 한글을 입력했을 때에 변환되는 Unicode와 내 소스에서 뱉어내는 Unicode가 완전히 달랐고, 하나하나 로그를 찍어보다보니 왠걸, OSX 환경때문에 생기는 이슈였다.
OSX는 한글을 조합되지 않은 상태로 기록한다. 그러니까 달
이라고 입력을 하고 실제로 그렇게 보이지만, 내부적으로는 ㄷㅏㄹ
이라고 저장한다. 달
을 Unicode로 치환한 값과 ㄷㅏㄹ
을 Unicode로 치환하는 값은 다르다. Unicode는 언어의 모양을 특정 키값에 저장하는데, 달
이라는 조합된 글자는 하나의 키에 저장되지만 ㄷㅏㄹ
은 각 글자수만큼 세개의 키에 저장이 된다.
Toonman은 Node.js로 제작 중이었고, OSX환경에서 fs
의 readdir()
을 통해 파일명을 읽어오니 실제 파일명과 다르게 조합되지 않은 형태의 파일명을 가져오고 있었다. (물론 표현할 때에 조합해주기 때문에 눈으로 보기에는 정상적으로 조합된 형태였다.)
로컬환경에서야 맥이 다시 값을 조합하기 때문에 문제없이 이미지의 URL을 읽어들일 수 있었지만, 서버에서는 해당 기능을 제공하지 않으니 이미지의 위치를 제대로 읽을리 만무했다.
달.jpg
를 호출해야 하는데 ㄷㅏㄹ.jpg
를 요청하고 있었던 것이다.
문제를 알았으니, 이제 OSX가 풀어해친 한글을 다시 조합하기만 하면 된다.
Unicode Normalizing
이렇게 풀어헤쳐진 Unicode를 다시 조합된 형태로 바꾸거나, 조합된 Unicode를 풀어헤치는 과정을 Unicode Normalizing
이라고 한다.
조합된 형태를 NFC
포맷, 풀어진 형태를 NFD
포맷이라고 하며, 그러니까 나는 NFD TO NFC
과정을 거쳐야 한다. Node.js에는 물론 UNORM이라는 NPM 도구가 이미 제작되어 있었다.
fs.readdir()
에서 리턴된 값을, UNORM
을 이용해 NFC
포맷으로 변환시켜주자 정상적으로 서버에서도 이미지를 읽어온다.