얼마전 kldp에서 제가 남겼던 코멘트들을 트래킹하는 도중! ICU에 charset detector가 포함되었단 소식을 듣게 되었습니다.
이 소식을 듣고 불이나게 ICU 문서를 뒤져봤지만, 문서가 굉장히 불친절하네요. -_-a
어쨌거나 IBM에서 만든 라이브러리 답게 C, C++, java 인터페이스를 모두 제공하고 있고, PHP에서도 intl 라이브러리를 통해 활용이 가능합니다만 아직 charset detector까지는 지원하고 있지 않습니다.
어쨌든 파일을 지정해서 어떤 charset인지를 알아내기 위한 코드는 다음과 같습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#include #include #include int main( int argc, char** argv ){ char buf[1024*1024+1]; FILE* in; UErrorCode err; UCharsetDetector* det; UCharsetMatch** match; int confidence; const char* charset; int i, num; if( argc != 2 ) return -1; if( (in = fopen(argv[1], "r")) == NULL ) return -1; fprintf( stderr, "%d bytes are read\n", fread( buf, 1, 1024*1024, in ) ); fclose(in); err = U_ZERO_ERROR; det = ucsdet_open(&err); if(U_FAILURE(err)) fprintf( stderr, "Error in open" ); ucsdet_setText(det, buf, strlen(buf), &err); if(U_FAILURE(err)) fprintf( stderr, "Error in set text" ); match = ucsdet_detectAll(det, &num, &err); if(U_FAILURE(err)) fprintf( stderr, "Error in detect" ); for( i = 0 ; i < num ; i++ ){ confidence = ucsdet_getConfidence(match[i], &err); if(U_FAILURE(err)) fprintf( stderr, "Error in confidence" ); charset = ucsdet_getName(match[i], &err); if(U_FAILURE(err)) fprintf( stderr, "Error in getName" ); fprintf( stdout, "%s, %d\n", charset, confidence ); } return 0; } |
ICU는 첨 써봤는데, 복잡하지 않아서 쉽게 활용하기 좋습니다만 불친절한 문서 덕에 어떤 라이브러리와 링크를 해야하는지를 찾는데 꽤 애를 먹어야했습니다. 참고로 위 코드를 컴파일하려면 icutu 라이브러리와 링크를 해야 합니다.
계정에 올려놓은 한글 텍스트 파일이 그리 많지 않아서 -_-a 테스트를 많이 해보진 못했지만 그럭저럭 잘 찾아내는 것 같네요. 제 스팸 필터에 활용을 해볼까 하고 본건데, 실제로 적용을 하려면 intl 부터 패치해야겠네요.
ICU 에서 Charset detecting 을 지원한지 꽤 되었는데, 아직 intl extension 이나 pecl/pcre library 에서 이상하게 지원하지 않더군요. 관심이 없는 것인지.. 그래서 mod_chardet extension 으로 만들어 보았습니다. Python C API 이용해서 python chardet 도 사용할 수 있고요. (성능은 구리지만..)
trackback 이 걸리지 않아서 댓글로 남겨 봅니다. http://my.oops.org/126 참조 하세요.