3 min read

node.js에서 iconv로 인코딩 변경 시 유의점

node.js에서 iconv로 인코딩 변경 시 유의점
Photo by Fernando @cferdophotography / Unsplash

node.js 연습 겸 알라딘 오프라인 중고서점으로부터 책 검색하는 짧은 코드를 작성하고 있는데, 알라딘 사이트가 utf-8이 아닌 euc-kr 인코딩을 사용하고 있어서 한글이 깨지는 문제가 있었다.
웹에서 찾아본 대로 iconv를 이용해 인코딩 변환 코드를 추가했는데 (늘 그렇듯이) 한번에 성공이 안되는 것이다.

약간의 우여곡절 끝에 해결할 수 있었는데, 웹 검색했을 때에는 달리 나오지 않는 문제라서, 나한테만 해당되는 특수한 상황일 수 있다. 하여튼 시행착오를 거쳐 두 가지를 배울 수 있었다.

인코딩 변환한 결과를 원래의 문자열 변수에 넣지 말자

var Iconv = require('iconv').Iconv;
// ...
var iconv = new Iconv('euc-kr', 'utf-8//translit//ignore');
searchResult = iconv.convert(searchResult).toString('utf-8');

코드 중 //translit//ignore는 인코딩 변환 과정 중에 이해할 수 없는 값이 입력됐을 경우 이를 어떻게든 바꾸거나 ('어떻게'인지는 잘 모른다) 아니면 무시하라고 알리는 것이다.
보통 웹에서 인코딩 변환 문제로 찾아보면 대부분 포함되어 있는데 이게 없으면 "Illegal character sequence" 에러를 내고 죽는다.
보통 입력 내용 중에 utf-8 데이터가 섞여있을 경우에 종종 발생한다고 하는데 마지막 라인 좌항의 searchResultsearchResultUtf8 식의 별도의 변수를 사용하니 피할 수 있었다.

내 생각으로는 iconv.convert() 함수가 입력을 받은 후 변환 결과를 제 3의 메모리 공간에 저장한 후 이를 반환하는 것일 거라고 짐작했었는데 바로 입력 공간(searchResult)에다 write 하는 것이었던 듯.

다음은 수정한 코드.

var Iconv = require('iconv').Iconv;
// ...
var iconv = new Iconv('euc-kr', 'utf-8');
var searchResultUtf8 = iconv.convert(searchResult).toString('utf-8');

인코딩 변환 전에 한번 Buffer 형의 버퍼에 넣어주자

죽지 않고 인코딩에 성공했는데, 그 결과가 '쨈쨈쨋짝...' 식으로 이상하게 깨져나왔다. 이건 占쏙옙과는 다른 문제이다.

이유는 모르겠지만, Buffer 형 변수에 한번 넣어주는 것으로 해결했다.

var Iconv = require('iconv').Iconv;
// ...
var iconv = new Iconv('euc-kr', 'utf-8');
var searchResultBin = new Buffer(searchResult, 'binary');
var searchResultUtf8 = iconv.convert(searchResultBin).toString('utf-8');

이미 한번 searchResultBin에 담았으므로, 이 경우 iconv.convert() 결과를 다시 searchResult에 담아도 무방할 것 같다.

— END OF POST.