Как я могу лучше всего угадать кодировку, если отсутствует спецификация (метка порядка байтов)?

Моя программа должна читать файлы, использующие различные кодировки. Это могут быть ANSI, UTF-8 или UTF-16 (с прямым или обратным порядком байтов).

Когда есть BOM (Byte Order Mark), у меня нет проблем. Я знаю, является ли файл UTF-8 или UTF-16 BE или LE.

Когда не было спецификации, я хотел предположить, что это файл ANSI. Но я обнаружил, что файлы, с которыми я работаю, часто не имеют своей спецификации. Следовательно, отсутствие спецификации может означать, что это файл ANSI, UTF-8, UTF-16 BE или LE.

Если у файла нет спецификации, как лучше всего просканировать часть файла и наиболее точно угадать тип кодировки? Я бы хотел быть почти в 100% случаев, если файл ANSI, и в высоких 90, если это формат UTF.

Я ищу общий алгоритмический способ определить это. Но на самом деле я использую Delphi 2009, который знает Unicode и имеет класс TEncoding, так что что-то специфическое для этого было бы бонусом.


Отвечать:

Ответ ShreevatsaR привел меня к поиску в Google "универсального детектора кодирования delphi", что удивило меня, когда этот пост оказался на позиции №1 после того, как был жив всего около 45 минут! Это быстрый googlebotting !! И еще удивительно, что Stackoverflow так быстро занял первое место.

Второй записью в Google была запись в блоге Фреда Икера на Обнаружение кодировки символов, в котором перечислены алгоритмы на разных языках.

Я нашел упоминание о Delphi на этой странице, и это привело меня прямо к бесплатному детектору кодировки ChsDet с открытым исходным кодом на SourceForge написан на Delphi и основан на компоненте Mozilla i18n.

Фантастика! Спасибо всем, кто ответил (всем +1), спасибо ShreevatsaR, и еще раз спасибо Stackoverflow, за то, что помог мне найти мой ответ менее чем за час!


person lkessler    schedule 16.12.2008    source источник
comment
Спасибо за редактирование! ChsDet вроде работает!   -  person Edwin Yip    schedule 22.02.2012


Ответы (4)


Возможно, вы сможете использовать сценарий Python, который использует Chardet: Universal Encoding Detector. Это повторная реализация обнаружения кодировки символов, используемого Firefox, и используется многими различными приложениями.. Полезные ссылки: код Mozilla, исследовательский документ, на котором он был основан (по иронии судьбы мой Firefox не может правильно определить кодировку этой страницы), < href = "http://chardet.feedparser.org/docs/faq.html#faq.impossible" rel = "noreferrer"> краткое объяснение, подробное объяснение.

person Community    schedule 16.12.2008
comment
Оооо. Это именно тот тип алгоритма, который я ищу. Если бы я мог понять, как это работает, или просто нашел бы эквивалент Delphi ... - person lkessler; 17.12.2008
comment
Согласно документам, это порт Python для кода Mozilla cpp. Последний находится по адресу mxr.mozilla.org/seamonkey/source/ extension / universalchardet / Но я не знаю, какое воплощение легче портировать! - person Marek Jedliński; 17.12.2008
comment
(продолжение) Версия CPP, кажется, более подробно прокомментирована, что может помочь при портировании. - person Marek Jedliński; 17.12.2008
comment
Все ссылки умерли. Можете попробовать их восстановить? - person Jeroen Wiert Pluimers; 21.03.2014

Вот как это делает блокнот

Существует также универсальный детектор кодировки Python, который вы можете проверить.

person Igal Serban    schedule 16.12.2008
comment
IsTextUnicode - хороший первый шаг. Затем он говорит, что использует ietf.org/rfc/rfc2279.txt?number=2279 для определения UTF-8, но здесь не говорится, что тестировать. - person lkessler; 17.12.2008
comment
На самом деле, WP, это en.wikipedia.org/wiki/Bush_hid_the_facts (некоторые шутки должны поясняться). - person Alan Moore; 17.12.2008
comment
Собственно моя версия - М.С. скрыла факты (конечно, без кавычек). Попробуй. - person Windows programmer; 17.12.2008

Я предполагаю:

  • Сначала проверьте, имеет ли файл байтовые значения меньше 32 (кроме табуляции / новой строки). Если да, то это не может быть ANSI или UTF-8. Таким образом - UTF-16. Просто нужно выяснить порядок байтов. Для этого вам, вероятно, следует использовать некоторую таблицу допустимых кодов символов Unicode. Если вы обнаружите недопустимые коды, попробуйте другой порядок байтов, если он подходит. Если подходит (или нет), проверьте, какой из них имеет больший процент буквенно-цифровых кодов. Также вы можете попробовать поискать разрывы строк и определить по ним порядок следования байтов. Кроме этого, у меня нет идей, как проверить порядок следования байтов.
  • Если файл не содержит значений меньше 32 (кроме указанного пробела), вероятно, это ANSI или UTF-8. Попробуйте разобрать его как UTF-8 и посмотрите, не появятся ли у вас недопустимые символы Unicode. Если да, то, вероятно, это ANSI.
  • Если вы ожидаете документы в неанглийской однобайтовой или многобайтовой кодировке, отличной от Unicode, то вам не повезло. Лучшее, что вы можете сделать, - это что-то вроде Internet Explorer, который составляет гистограмму значений символов и сравнивает ее с гистограммами известных языков. Довольно часто это срабатывает, но иногда и дает сбой. И вам понадобится большая библиотека гистограмм букв для каждого языка.
person Vilx-    schedule 16.12.2008
comment
Хммм, я часто вижу в своих текстовых файлах байты со значениями меньше 32. Такие вещи, как \ n, \ r и \ t. Редко и другие. - person Michael Burr; 17.12.2008
comment
ASCII, большинство кодовых страниц ANSI и UTF-8 понимают символы, такие как возврат каретки, перевод строки, горизонтальная табуляция, нулевой символ и т. Д., Которые имеют байтовые значения меньше 32. - person Windows programmer; 17.12.2008
comment
Я хотел сказать в вопросе ANSI, а не ASCII. Я изменил вопрос сейчас. Вы можете изменить свой ответ, чтобы отразить это. - person lkessler; 17.12.2008

ASCII? Никакая современная ОС больше не использует ASCII. Все они используют как минимум 8-битные коды, то есть это либо UTF-8, ISOLatinX, WinLatinX, MacRoman, Shift-JIS, либо что-то еще.

Единственный известный мне тест - это проверка недопустимых символов UTF-8. Если вы их найдете, значит, это не может быть UTF-8. То же самое, вероятно, возможно и для UTF-16. Но если Unicode не установлен, будет сложно определить, какая это кодовая страница Windows.

Большинство известных мне редакторов справляются с этим, позволяя пользователю выбрать значение по умолчанию из списка всех возможных кодировок.

Есть код для проверки действительности символов UTF.

person Thomas Tempelmann    schedule 16.12.2008
comment
В Windows все еще есть драйверы устройств. Если ваш код ядра не является 7-битным, вы пожалеете об этом. - person Windows programmer; 17.12.2008
comment
@ Windows-программист: что значит код ядра должен быть 7-битным? Большинство (все?) Драйверов должны иметь дело с Unicode - хотя иногда проблема заключается в правильном преобразовании из MBCS в Unicode (использовать OEM или кодовую страницу по умолчанию? И т. Д.). - person Michael Burr; 17.12.2008
comment
Хорошо, код, который обрабатывает имена файлов, должен копировать и преобразовывать символьные строки в переменные (PUNICODE и т. Д.), Но исходный код по-прежнему должен быть 7-битным чистым, чтобы правильно компилировать во время компиляции. - person Windows programmer; 17.12.2008