DLL для определения кодировки?
Модераторы: Avada, CaptainFlint, Nik, d-view, Моторокер
DLL для определения кодировки?
Ищется код(лучше- DLL!) для определния кодировки файла, если нету BOM. По первым NN Кб. Для плагина Syn2.
если код на С, я его использовать не могу.
если код на С, я его использовать не могу.
Насколько я понимаю, нужно определить UTF-8 или нет, т.к. BOM к другого рода кодировкам (типа 1251, KOI-8 ) не имеет отношения. Я пользуюсь такой функцией (где-то когда-то нашел):
Код: Выделить всё
function IsUTF8Memory(AMem: PBYTE; ASize: Int64): boolean;
var
i: Int64;
c: Integer;
function UTF8CharLength(const c: BYTE): Integer;
begin
// First Byte: 0xxxxxxx
if ((c and $80) = $00) then
Result:=1
// First Byte: 110yyyyy
else if ((c and $E0) = $C0) then
Result:=2
// First Byte: 1110zzzz
else if ((c and $F0) = $E0) then
Result:=3
// First Byte: 11110uuu
else if ((c and $F8) = $F0) then
Result:=4
// not valid, return the error value
else
Result:=-1;
end;
//After than you check all the trail bytes for that characters (if any)
//for conformity with this:
function UTF8IsTrailChar(const c: BYTE): BOOLEAN;
begin
// trail bytes have this form: 10xxxxxx
Result:=((c and $C0) = $80);
end;
begin
Result := True;
i := 0;
while (i < ASize) do
begin
// get the length if the current UTF-8 character
c:=UTF8CharLength(AMem^);
// check if it is valid and fits into ASize
if ((c>= 1) and (c <= 4) and ((i+c-1) < ASize)) then
begin
inc(i, c);
inc(AMem);
// if it is a multi-byte character, check the trail bytes
while (c>1) do
begin
if (not UTF8IsTrailChar(AMem^)) then
begin
Result := False;
break;
end
else
begin
dec(c);
inc(AMem);
end;
end;
end
else
begin
Result:=False;
end;
if (not Result) then break;
end;
end;
Определение этих кодировок - уже по-любому статистические алгоритмы. Их вроде найти не проблема. Например, вот. Сначала определяем, UTF-8 ли текст, и если нет - смотрим кодировку.
Определение этих кодировок уже зависит от кодовой страницы. Для русской будет один результат, для каких-нибудь еще - другой. Наверное можно попробовать составить список букв, действительных для каждой кодировки, и подсчитывать число букв текста, совпадающих с ними - где будет больше, та кодировка скорее используется. Но опять же, до какой-то степени множества символов кодировок пересекаются - на поле в 128 символов особо не разгуляешься.
Alextp
Вот мой код чуть более общий:
А среди 8-битных делал только на C#. Определяло практически всё правильно. Если надо скину.
Вот мой код чуть более общий:
Код: Выделить всё
type
TEncodingType = (ANSI, UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE);
function DetectEncodingType(hOpenedFile: Cardinal): TEncodingType;
//вялое определние кодировки
//файл должен быть уже открыт на чтение
var
buf: array[0..3] of AnsiChar;
begin
Result := ANSI;
FileRead(hOpenedFile, buf, 4);
case buf[0] of
#$EF:
begin
if (buf[1] = #$BB) and (buf[2] = #$BF) then
begin
FileSeek(hOpenedFile, 3, spBegin);
Result := UTF8;
end;
end;
#$FE:
begin
if (buf[1] = #$FF) then
FileSeek(hOpenedFile, 2, spBegin);
Result := UTF16BE;
end;
#$FF:
begin
if (buf[1] = #$FE) then
if (buf[2] = #$00) and (buf[3] = #$00) then
begin
FileSeek(hOpenedFile, 4, spBegin);
Result := UTF32LE;
end
else
begin
FileSeek(hOpenedFile, 2, spBegin);
Result := UTF16LE;
end;
end;
#$00:
begin
if (buf[1] = #$00) and (buf[2] = #$FE) and (buf[3] = #$FF) then
begin
FileSeek(hOpenedFile, 4, spBegin);
Result := UTF32BE;
end;
end;
else
FileSeek(hOpenedFile, 0, spBegin);
end;
end;kIT Programs PowerPack, kIT Universal Presets | Есть только одна истинная вера: чёрная магия...
- CaptainFlint
- Сообщения: 6239
- Зарегистрирован: Вт дек 14, 2004 22:34
- Контактная информация:
Alextp
В общем случае задача неразрешима, потому что если текст целиком на английском, то в ANSI и UTF-8 он будет выглядеть идентично. Да и сам по себе UTF-8 принципиально от ANSI не отличается. Так что как минимум возникает вопрос о приоритетах списка кодировок.
Тому, кто захочет этим заниматься, могу подкинуть лишь идею для реализации, основанную на поведении Тотала (CompareUtf8Detect): пробежаться по файлу, оценивая его с точки зрения допустимости в UTF-8. Если встретилась хотя бы одна недопустимая последовательность байтов, значит, это ANSI. Если встретилась хотя бы одна допустимая мультибайтовая последовательность — с определённым риском можно считать, что это UTF-8 (хотя реально это может быть и ANSI, гарантий нет). Если нет ни того, ни другого, то выбор между ANSI и UTF-8 придётся делать волевым решением (или опцией). Дополнительно (опять-таки, по мотивам Тотала) можно для HTML/XML/CSS-файлов поискать сигнатуры кодировок и встроить их в описанный алгоритм предпочтений.
Следующий уровень для наворотов — учёт языковых особенностей (что если файл русскоязычный, то большинство символов там будет не просто UTF-8, а из конкретного диапазона), но это очень опасный шаг, если методика планируется для повсеместного применения: каждый язык придётся изучать на предмет алфавита и используемых символов, для каждого хардкодить списки последовательностей… Плюс есть вероятность, что из-за этих наворотов точность определения кодировки для неизвестных языков уменьшится, и придётся либо активно дорабатывать списки символов для большого количества языков (возможно, тем самым ещё сильнее ухудшая работу с оставшимися неподдерживающимися языками), либо предусматривать конфигурируемость алгоритма.
В общем случае задача неразрешима, потому что если текст целиком на английском, то в ANSI и UTF-8 он будет выглядеть идентично. Да и сам по себе UTF-8 принципиально от ANSI не отличается. Так что как минимум возникает вопрос о приоритетах списка кодировок.
Тому, кто захочет этим заниматься, могу подкинуть лишь идею для реализации, основанную на поведении Тотала (CompareUtf8Detect): пробежаться по файлу, оценивая его с точки зрения допустимости в UTF-8. Если встретилась хотя бы одна недопустимая последовательность байтов, значит, это ANSI. Если встретилась хотя бы одна допустимая мультибайтовая последовательность — с определённым риском можно считать, что это UTF-8 (хотя реально это может быть и ANSI, гарантий нет). Если нет ни того, ни другого, то выбор между ANSI и UTF-8 придётся делать волевым решением (или опцией). Дополнительно (опять-таки, по мотивам Тотала) можно для HTML/XML/CSS-файлов поискать сигнатуры кодировок и встроить их в описанный алгоритм предпочтений.
Следующий уровень для наворотов — учёт языковых особенностей (что если файл русскоязычный, то большинство символов там будет не просто UTF-8, а из конкретного диапазона), но это очень опасный шаг, если методика планируется для повсеместного применения: каждый язык придётся изучать на предмет алфавита и используемых символов, для каждого хардкодить списки последовательностей… Плюс есть вероятность, что из-за этих наворотов точность определения кодировки для неизвестных языков уменьшится, и придётся либо активно дорабатывать списки символов для большого количества языков (возможно, тем самым ещё сильнее ухудшая работу с оставшимися неподдерживающимися языками), либо предусматривать конфигурируемость алгоритма.
Почему же, ё-моё, ты нигде не пишешь "ё"?
Вот неплохая библиотека (исходники на delphi), может быть использована как напрямую из кода, так и в виде dll.