View previous topic :: View next topic |
Author |
Message |
Alextp
Joined: 06 Feb 2005 Posts: 4957
|
(Separately) Posted: Mon Aug 16, 2010 23:32 Post subject: DLL для определения кодировки? |
|
|
Ищется код(лучше- DLL!) для определния кодировки файла, если нету BOM. По первым NN Кб. Для плагина Syn2.
если код на С, я его использовать не могу. _________________ UniViewer - CudaText - LogViewer
|
|
Back to top |
|
|
Alextp
Joined: 06 Feb 2005 Posts: 4957
|
(Separately) Posted: Tue Aug 17, 2010 00:29 Post subject: |
|
|
Посмотрел код akelpad- непонятно, какие-то watermarks-массивы, что они значат не понял (а тупо переводить код не хочется) _________________ UniViewer - CudaText - LogViewer
|
|
Back to top |
|
|
Loopback
Joined: 07 Sep 2009 Posts: 1297
|
(Separately) Posted: Tue Aug 17, 2010 09:45 Post subject: |
|
|
Насколько я понимаю, нужно определить UTF-8 или нет, т.к. BOM к другого рода кодировкам (типа 1251, KOI-8 ) не имеет отношения. Я пользуюсь такой функцией (где-то когда-то нашел):
Code: |
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;
|
|
|
Back to top |
|
|
Alextp
Joined: 06 Feb 2005 Posts: 4957
|
|
Back to top |
|
|
Loopback
Joined: 07 Sep 2009 Posts: 1297
|
(Separately) Posted: Tue Aug 17, 2010 10:35 Post subject: |
|
|
Определение этих кодировок - уже по-любому статистические алгоритмы. Их вроде найти не проблема. Например, вот. Сначала определяем, UTF-8 ли текст, и если нет - смотрим кодировку. |
|
Back to top |
|
|
Alextp
Joined: 06 Feb 2005 Posts: 4957
|
|
Back to top |
|
|
MVV
Joined: 15 Oct 2009 Posts: 4811 Location: Ростов-Дон
|
(Separately) Posted: Tue Aug 17, 2010 12:53 Post subject: |
|
|
Определение этих кодировок уже зависит от кодовой страницы. Для русской будет один результат, для каких-нибудь еще - другой. Наверное можно попробовать составить список букв, действительных для каждой кодировки, и подсчитывать число букв текста, совпадающих с ними - где будет больше, та кодировка скорее используется. Но опять же, до какой-то степени множества символов кодировок пересекаются - на поле в 128 символов особо не разгуляешься. _________________ TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel… |
|
Back to top |
|
|
Alextp
Joined: 06 Feb 2005 Posts: 4957
|
(Separately) Posted: Sat Jan 21, 2012 21:30 Post subject: |
|
|
(Up)
Кто-нибудь может за небольшую плату сделать dll, для определения "'это - UTF8 без BOM", с настройкой "для русского/ немецкого/ ..... "? могу дать пример на C. из сорса Notepad++.
Добавлено спустя 40 секунд:
точнее Akelpad _________________ UniViewer - CudaText - LogViewer
|
|
Back to top |
|
|
ApceH
Joined: 08 Apr 2011 Posts: 316 Location: Димитровград
|
(Separately) Posted: Sat Jan 21, 2012 23:19 Post subject: |
|
|
Alextp
Вот мой код чуть более общий:
Code: | 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; |
А среди 8-битных делал только на C#. Определяло практически всё правильно. Если надо скину. _________________ kIT Programs PowerPack, kIT Universal Presets | Есть только одна истинная вера: чёрная магия... |
|
Back to top |
|
|
Alextp
Joined: 06 Feb 2005 Posts: 4957
|
|
Back to top |
|
|
CaptainFlint
Joined: 14 Dec 2004 Posts: 6151 Location: Москва
|
(Separately) Posted: Sun Jan 22, 2012 14:33 Post subject: |
|
|
Alextp
В общем случае задача неразрешима, потому что если текст целиком на английском, то в ANSI и UTF-8 он будет выглядеть идентично. Да и сам по себе UTF-8 принципиально от ANSI не отличается. Так что как минимум возникает вопрос о приоритетах списка кодировок.
Тому, кто захочет этим заниматься, могу подкинуть лишь идею для реализации, основанную на поведении Тотала (CompareUtf8Detect): пробежаться по файлу, оценивая его с точки зрения допустимости в UTF-8. Если встретилась хотя бы одна недопустимая последовательность байтов, значит, это ANSI. Если встретилась хотя бы одна допустимая мультибайтовая последовательность — с определённым риском можно считать, что это UTF-8 (хотя реально это может быть и ANSI, гарантий нет). Если нет ни того, ни другого, то выбор между ANSI и UTF-8 придётся делать волевым решением (или опцией). Дополнительно (опять-таки, по мотивам Тотала) можно для HTML/XML/CSS-файлов поискать сигнатуры кодировок и встроить их в описанный алгоритм предпочтений.
Следующий уровень для наворотов — учёт языковых особенностей (что если файл русскоязычный, то большинство символов там будет не просто UTF-8, а из конкретного диапазона), но это очень опасный шаг, если методика планируется для повсеместного применения: каждый язык придётся изучать на предмет алфавита и используемых символов, для каждого хардкодить списки последовательностей… Плюс есть вероятность, что из-за этих наворотов точность определения кодировки для неизвестных языков уменьшится, и придётся либо активно дорабатывать списки символов для большого количества языков (возможно, тем самым ещё сильнее ухудшая работу с оставшимися неподдерживающимися языками), либо предусматривать конфигурируемость алгоритма. _________________ Почему же, ё-моё, ты нигде не пишешь "ё"? |
|
Back to top |
|
|
Alextp
Joined: 06 Feb 2005 Posts: 4957
|
(Separately) Posted: Sun Jan 22, 2012 15:55 Post subject: |
|
|
Нужно не "общий случай", а хотя бы как. Как сделано в Akelpad. хотя бы
А навороты не нужны пока
Добавлено спустя 3 минуты:
PS. спасибо, что расписал. _________________ UniViewer - CudaText - LogViewer
|
|
Back to top |
|
|
Alextp
Joined: 06 Feb 2005 Posts: 4957
|
|
Back to top |
|
|
Chusik
Joined: 26 May 2007 Posts: 11 Location: Волгоград
|
(Separately) Posted: Fri Jan 27, 2012 17:50 Post subject: |
|
|
Вот неплохая библиотека (исходники на delphi), может быть использована как напрямую из кода, так и в виде dll. |
|
Back to top |
|
|
|