
Как узнать кодировку текста
Для корректного отображения или передачи текстов надо знать, в какой кодировке этот текст записан. Есть инструменты для статистического анализа в виде внешних dll или библиотек на различных языках программирования. А я в этой статье расскажу, как можно решить подобную задачу с использованием системного интерфейса IMultiLanguage2. Насколько мне известно, этот интерфейс создавался для использования в браузере Internet Explorer, в том числе с целью определения кодировок web-страниц.Как вы могли догадаться, поскольку планируется работа с COM, то первым делом понадобятся GUID'ы и описания интерфейсов.
Code (Assembler) : Убрать нумерацию
- ; GUID {275C23E2-3747-11D0-9FEA-00AA003F8646}
- CLSID_CMultiLanguage \
- dd 0275C23E2h
- dw 03747h
- dw 011D0h
- db 09Fh, 0EAh, 000h, 0AAh, 000h, 03Fh, 086h, 046h
- ; GUID {DCCFC164-2B38-11D2-B7EC-00C04F8F5D9A}
- IID_IMultiLanguage2 \
- dd 0DCCFC164h
- dw 02B38h
- dw 011D2h
- db 0B7h, 0ECh, 000h, 0C0h, 04Fh, 08Fh, 05Dh, 09Ah
- ; IID_IMultiLanguage2 Interface
- struct IMultiLanguage2
- ; IUnknown
- QueryInterface dd ? ; 000h
- AddRef dd ? ; 004h
- Release dd ? ; 008h
- ; IMultiLanguage2
- GetNumberOfCodePageInfo dd ? ; 00Ch
- GetCodePageInfo dd ? ; 010h
- GetFamilyCodePage dd ? ; 014h
- EnumCodePages dd ? ; 018h
- GetCharsetInfo dd ? ; 01Ch
- IsConvertible dd ? ; 020h
- ConvertString dd ? ; 024h
- ConvertStringToUnicode dd ? ; 028h
- ConvertStringFromUnicode dd ? ; 02Ch
- ConvertStringReset dd ? ; 030h
- GetRfc1766FromLcid dd ? ; 034h
- GetLcidFromRfc1766 dd ? ; 038h
- EnumRfc1766 dd ? ; 03Ch
- GetRfc1766Info dd ? ; 040h
- CreateConvertCharset dd ? ; 044h
- ConvertStringInIStream dd ? ; 048h
- ConvertStringToUnicodeEx dd ? ; 04Ch
- ConvertStringFromUnicodeEx dd ? ; 050h
- DetectCodepageInIStream dd ? ; 054h
- DetectInputCodepage dd ? ; 058h
- ValidateCodePage dd ? ; 05Ch
- GetCodePageDescription dd ? ; 060h
- IsCodePageInstallable dd ? ; 064h
- SetMimeDBSource dd ? ; 068h
- GetNumberOfScripts dd ? ; 06Ch
- EnumScripts dd ? ; 070h
- ValidateCodePageEx dd ? ; 074h
- ends
- struct DetectEncodingInfo
- nLangID dd ?
- nCodePage dd ?
- nDocPercent dd ?
- nConfidence dd ?
- ends
- MLDETECTCP_NONE = 0
В общих чертах код определения кодировки будет выглядеть примерно так. Создаем интерфейс IMultiLanguage2, затем через указанный выше метод получаем данные о кодировке или нескольких кодировках, если требуется именно такой вариант.
Code (Assembler) : Убрать нумерацию
- ; Инициализация COM
- invoke CoInitialize,NULL
- ; Создать объект
- invoke CoCreateInstance,CLSID_CMultiLanguage,NULL,\
- CLSCTX_INPROC_SERVER,IID_IMultiLanguage2,\
- pMultiLanguage
- ; Первая строка
- mov [scores],1
- ; Длина строки
- invoke lstrlen,string1
- mov [str_len],eax
- mov eax, [pMultiLanguage]
- mov eax, [eax]
- stdcall dword [eax+IMultiLanguage2.DetectInputCodepage],\
- [pMultiLanguage],\
- MLDETECTCP_NONE,0,\
- string1,str_len,\
- deinfo,scores
- mov eax,deinfo
- ; [deinfo.nDocPercent] - процент символов в строке с этой кодировкой
- ; [deinfo.nConfidence] - достоверность результата
- ; Получить подробную информацию о кодировке
- invoke GetCPInfoEx,[deinfo.nCodePage],0,cpinfo
- ; Прибраться за собой
- mov eax, [pMultiLanguage]
- mov eax, [eax]
- stdcall dword [eax+IMultiLanguage2.Release],[pMultiLanguage]
- invoke CoUninitialize
В полях структур DetectEncodingInfo содержится информация о языке и кодировке, в поле nDocPercent содержится процентное количество символов в исходной строке, которые соответствуют этой кодировке. В поле nConfidence записан коэффициент достоверности, чем это значение больше, тем точнее определена кодировка. Что интересно, это не процентное значение, так как оно запросто может оказаться больше 100.
После получения списка кодировок можно пройтись по массиву, в частности по полям nCodePage, и уточнить человекопонятную информацию по каждой из них. Нечто подобное мы уже делали.
Ну и конечно же надо понимать, что любой автоматический способ определения кодировки текста не дает 100% точности. Однако, описанного в статье способа в подавляющем большинстве случаев будет достаточно.
В приложении пример программы с исходным текстом, которая определяет и выводит на экран кодировки для двух разных строк.
Просмотров: 544 | Комментариев: 0

Комментарии
Отзывы посетителей сайта о статье
Комментариeв нет

Добавить комментарий
Заполните форму для добавления комментария
