Search Results for 'Mozilla Chardet'


1 POSTS

  1. 2009/02/19 Charset Detecting on PHP by 김정균 (14)

Charset Detecting on PHP

문서의 Charset 을 detecting 하는 library 로는 IBM 이 지원하는 International Components for Unicode (ICU Project) 의 ICU library 와 Mozilla Browser 에서 이용하는 Universal Chardet library 가 있습니다.

ICU 의 경우에는 charset detect 가 포함된지 꽤 되었음에도 불구하고, php 5.3 부터 기본 포함되는 intl extension 에는 이 기능이 들어가지 않고 있습니다. 그 외에도 pecl 이나 pear 의 icu library 관련 패키지들에도 이상하게 이 부분만 들어가지 않고 있군요.

그리고 좀 더 안습인 것은, Mozilla 의 Universal Chardet 의 경우에는 C#, java, python, ruby (python chardet 을 porting 했음) 등등이 지원하고 있음에도 불구하고, PHP 나 별도의 c/c++ library 로는 제공되지 않고 있습니다.

Mozilla Universal Charset
Nchardet for C#
jchardet for Java
chardet for python
rchardet for ruby (python clone
Encode-Detect-1.01 > Encode::Detect::Detector for perl

mozilla code 에 c++ 로 지원하고 있으니 이걸 포팅하면 되겠지 하고 쉽게 생각을 했는데, xpcom 구조를 알기 전에는 쉽게 뗄 수 있을 놈이 아니더군요.

이렇듯 저렇듯.. 나오기만 2여년을 기다리다가.. 귀찮아서 mod_chardet 이라는 php extension 으로 하나 만들어 보고 말았습니다. 일단 mod_chardet 은 기본은 ICU library 의 Charset detect 기능을 이용하고, 옵션으로 python chardet 이 설치가 되어 있으면 Python C API를 이용하여 python chardet 을 사용할 수 있도록 설계를 했습니다. Mozilla Universal chardet 이 PHP 만 없다는 것도 좀 그렇다는 생각이 들었고..

일단, ICU 와 Universal Chardet 의 성능 비교도 해 볼겸해서 돌려 보았는데, 역시 ICU 보다는 Universal Chardet 이 detect 능력이 좋더군요. 그리고 ICU 에서 detect 할 수 있는 charset 보다 Universal chardet 이 좀 더 많이 지원하는 까닭도 있었고요.

일단, python chardet homepage 에 있는 자료가 오래된 까닭에 다음의 환경에서 해당 자료를 다시 분석해 보았습니다.

테스트 환경으로는 다음과 같습니다.

Python 2.5
Python Chardet 1.0.1
PHP 5.2.6
ICU library 4.0.1

Python Chardet result: google.cn {'confidence': 0.98999999999999999, 'encoding': 'GB2312'} yahoo.jp {'confidence': 0.98999999999999999, 'encoding': 'utf-8'} amazon.co.jp {'confidence': 1, 'encoding': 'SHIFT_JIS'} pravda.ru {'confidence': 0.93312187961594417, 'encoding': 'windows-1251'} auction.co.kr {'confidence': 0.56471064895612277, 'encoding': 'ISO-8859-2'} haaretz.co.il {'confidence': 0.98999999999999999, 'encoding': 'windows-1255'} www.nectec.or.th {'confidence': 0.77645629965698426, 'encoding': 'TIS-620'} feedparser.org {'confidence': 0.98999999999999999, 'encoding': 'utf-8'}


python-chardet 1.0.1 의 경우, 홈페이지 자료와는 약간 다른 결과가 나오더군요. 일단 python chardet homepage 의 정보가 변경이 되었을 수도 있고, chardet 이 업데이트 되면서 결과가 달라질 수도 있겠지만, 일단 이 결과에서 auction 이 예전에는 제대로 EUC-KR로 판단이 되었는데, 지금 환경에서는 다른 결과를 보여 주고 있습니다.

다음은 mod_chardet 의 결과 입니다.

PHP mod_chardet result: google.cn (7121) ICU : Encoding -> GB18030 Confidence -> 100 MOZ : Encoding -> GB2312 Confidence -> 98 yahoo.jp (30367) ICU : Encoding -> UTF-8 Confidence -> 100 MOZ : Encoding -> utf-8 Confidence -> 98 amazon.co.jp (166082) ICU : Encoding -> Shift_JIS Confidence -> 100 MOZ : Encoding -> SHIFT_JIS Confidence -> 100 pravda.ru (97826) ICU : Encoding -> ISO-8859-1 Confidence -> 28 MOZ : Encoding -> windows-1251 Confidence -> 93 auction.co.kr (101330) ICU : Encoding -> EUC-KR Confidence -> 100 MOZ : Encoding -> ISO-8859-2 Confidence -> 56 haaretz.co.il (174179) ICU : Encoding -> ISO-8859-1 Confidence -> 32 MOZ : Encoding -> windows-1255 Confidence -> 98 www.nectec.or.th (41527) ICU : Encoding -> ISO-8859-1 Confidence -> 37 MOZ : Encoding -> TIS-620 Confidence -> 77 feedparser.org (28443) ICU : Encoding -> UTF-8 Confidence -> 100 MOZ : Encoding -> utf-8 Confidence -> 98 18.33 Sec


보시다 시피, CJK / UTF-8 / ASCII 를 제외한 다른 1byte 권의 언어들에 대해서는 Universal chardet 이 ICU chardet 보다 월등히 detecting 을 잘 하고 있습니다. 다만 안습인 것은, mod_charset 의 Universal chardet 이 Python C API 를 이용해서 python 을 호출하다 보니, ICU 보다 성능이 굉장히 많이 떨어집니다. 실제로 위의 결과를 Universal chadet 체크를 하지 않는다면, 대략 0.04초 정도에 결과가 나옵니디만, Universal chardet detecting 을 시키니 거의 20초 가까운 결과치가 나옵니다.

대략 테스트를 해 보니 문자열이 3K 정도가 넘어가면 Python C API 로 호출한 결과가 상당히 늦어지는 결과를 보이더군요. 대략 1K 이내의 경우에 어느정도 비슷한 속도가 나옵니다.

또한, 짧은 문자열에 대해서도 ICU 보다 Universal chardet 이 성능이 조금 더 좋더군요. 그래도 한글 기준으로 테스트를 했을 때, 한글 10글자 정도는 받아야지 왠만한 confidence 가 나오게 됩니다.

다음의 결과는 web page 에서 html code 를 삭제하고 나온 결과 입니다. 다음의 코드가 사용이 되었습니다.

$buf = preg_replace ('/<[^>]*>/', '', $buf);


보통 웹 페이지의 경우, <>로 쌓여져 있는 코드들은 대부분 ASCII 이기 때문에 확률적 판단을 하는 chardet 에 부정적인 영향을 줄것이라 생각을 하고 한번 시도를 해 보았습니다.

PHP mod_chardet result: google.cn (2781) ICU : Encoding -> GB18030 Confidence -> 100 MOZ : Encoding -> GB2312 Confidence -> 98 yahoo.jp (3561) ICU : Encoding -> UTF-8 Confidence -> 100 MOZ : Encoding -> utf-8 Confidence -> 98 amazon.co.jp (30739) ICU : Encoding -> Shift_JIS Confidence -> 100 MOZ : Encoding -> SHIFT_JIS Confidence -> 100 pravda.ru (15728) ICU : Encoding -> windows-1251 Confidence -> 28 MOZ : Encoding -> windows-1251 Confidence -> 94 auction.co.kr (36084) ICU : Encoding -> EUC-KR Confidence -> 100 MOZ : Encoding -> ISO-8859-2 Confidence -> 27 haaretz.co.il (44570) ICU : Encoding -> ISO-8859-8-I Confidence -> 23 MOZ : Encoding -> windows-1255 Confidence -> 98 www.nectec.or.th (10425) ICU : Encoding -> EUC-JP Confidence -> 64 MOZ : Encoding -> TIS-620 Confidence -> 76 feedparser.org (5854) ICU : Encoding -> UTF-8 Confidence -> 100 MOZ : Encoding -> utf-8 Confidence -> 98 4.86 Sec


이렇게 detecting 을 하니 ICU의 결과가 조금 좋아졌으며 (하지만 오판하는 경우도 생겼군요), 텍스트 양이 줄면서 Python C API를 사용하는 Univiersal chardet 의 성능이 대략 5초 정도로 시간이 절약 되었습니다.

머 어쨌든 두가지 기능을 다 지원을 하고, PHP 에서도 Universal chardet 을 지원할 수 있다는 점에 일단은 만족을 하고, posting 과 함께 mod_chardet 을 공개합니다.

그리고 혹시나 단순히 euc-kr / utf-8 만 판단을 해야 한다면, chardet 은 overhead 일 경우가 많습니다. 이럴 경우에는 차라리 pear KSC5601에 있는 is_utf8 method 를 사용하시는 것이 훨씬 경제적/성능적 효과가 좋습니다. 물론 제가 만들어 놓은 것입니다 ^^;

코드는 http://cvs.oops.org/index.php?cvsroot=PHP-Module 에서 받으실 수 있으며, 소스 안의 test.php 를 참조 하시면 사용하시는데 별 무리는 없을 겁니다.

Posted by 김정균

2009/02/19 05:12 2009/02/19 05:12

Trackback URL : http://my.oops.org/trackback/126


Valid XHTML 1.0 Transitional Valid CSS 2.0!
뭘 이런걸..

뭘 이런걸..

Notices

Categories

전체 (135)
주절주절 (27)
군이 (11)
둘째 사고 일지 (3)
Tech (94)

Calendar

«   2012/02   »
      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      

Site Stats