Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2003.02.17;
Скачать: [xml.tar.bz2];

Вниз

Koi8???   Найти похожие ветки 

 
!...Stel   (2002-12-31 08:51) [0]

Уважаемые, который день ломаю голову и не как не могу определить кодиравку Koi8. И что характерно, нет никаких соображений. Никто не знает, как это делается?


 
Gandalf   (2002-12-31 10:23) [1]

Как и все остальные, проверяешь часто вхождения символов из русского алфавита в предположении, что это "та" кодировка - эсли таких довольно много - значит это она и есть.


 
!...Stel   (2002-12-31 14:52) [2]

Проверкой символов здесь не получится, потому, что Koi похожа на ANSI1251. Вот пример такой проверки символов:
const
WinSymbols:PChar=#242#243#0;
KoiSymbols:PChar=#225#224#0;
var i,w,k,Handle:integer;
st,p:PChar;
begin
for i:=0 to SendMessage(Form1.RichEdit1.Handle,WM_GETTEXT, $FFD, longint(@st[0]))-1 do
begin
P:=WinSymbols;
while p[0]<>#0 do
begin
if p[0]=st[i] then
begin
inc(w);
end;
inc(p);
end;

P:=KoiSymbols;
while p[0]<>#0 do
begin
if p[0]=st[i] then
begin
inc(k);
end;
inc(p);
end;

if w>k then win:=true else koi:=true;

end;

Но врезультате получается, что w=k. Мож чё ещё посоветуете.


 
ggrisha   (2002-12-31 15:18) [3]

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


 
Gandalf   (2002-12-31 16:43) [4]

Да тут методики, которые не могут дать 100% результат, чемто сродни задаче ИИ и здавого смысла. Например частота встречи букв. Потом более 3 гласных подряд или 4 согласных в русском языке не бывает (искл. абревиатуры). Можно игнорировать слова начинающиеся с ы,ь,ъ - если такие есть кодировка не та. Или повторы ыы, ьь, ъъ, и т.п. Можно проверять на глупый регистр, ПрАвДа НеКоТоРЫЕ ЛюБяТ ХАКЕрский СтИлЬ. И другие не строгие правила. дальше идет только подключение словоря :)


 
!...Stel   (2003-01-01 09:59) [5]

Но я чувствую это будет так долго определяться, например если файлик размером так 1-2мб. А ещё потом перекодировать надо будет...


 
Anatoly Podgoretsky   (2003-01-01 10:56) [6]

Ну ты наверно в курсе, что файл можно не обрабатывать полностью


 
don-do   (2003-01-03 11:23) [7]

Можно воспользоваться тем что в cp1251 первыми идут заглавные буквы а в KOI8-r прописные, по правилам русского языка слова состоят или из одинаковых букв или начинаются с заглавной, хотя написать можно по всякому.


 
bolega   (2003-01-05 13:44) [8]

Вот кусок из моей рабочей проги.
Автора алгоритма не знаю.

Часть 1.

const
DOS_2_Win: array[$80..$FF] of byte=(
$C0,$C1,$C2,$C3,$C4,$C5,$C6,$C7,$C8,$C9,$CA,$CB,$CC,$CD,$CE,$CF,
$D0,$D1,$D2,$D3,$D4,$D5,$D6,$D7,$D8,$D9,$DA,$DB,$DC,$DD,$DE,$DF,
$E0,$E1,$E2,$E3,$E4,$E5,$E6,$E7,$E8,$E9,$EA,$EB,$EC,$ED,$EE,$EF,
$B0,$B1,$B2,$A6,$B4,$B5,$B6,$B7,$B8,$B9,$BA,$BB,$BC,$BD,$BE,$AC,
$C0,$C1,$C2,$C3,$C4,$86,$C6,$C7,$C8,$C9,$CA,$CB,$CC,$CD,$CE,$CF,
$D0,$D1,$D2,$D3,$D4,$D5,$D6,$D7,$87,$D9,$DA,$DB,$DC,$DD,$DE,$DF,
$F0,$F1,$F2,$F3,$F4,$F5,$F6,$F7,$F8,$F9,$FA,$FB,$FC,$FD,$FE,$FF,
$A8,$B8,$AA,$BA,$AF,$BF,$A1,$A2,$B0,$F9,$B7,$FB,$B9,$A4,$FE,$A0);

KOI_2_DOS: array[$80..$FF] of Byte = (
$C4,$C3,$Da,$BF,$C0,$D9,$C3,$B4,$C2,$C1,$C5,$DF,$DC,$DB,$DD,$DE,
$B0,$B1,$b2,$f4,$fe,$f9,$fb,$f7,$f3,$f2,$ff,$f5,$f8,$fd,$fa,$f6,
$cd,$ba,$d5,$f1,$d6,$c9,$b8,$b7,$bb,$d4,$d3,$c8,$be,$bd,$bc,$c6,
$c7,$cc,$b5,$f0,$b6,$b9,$d1,$d2,$cb,$cf,$d0,$ca,$d8,$d7,$ce,$fc,
$ee,$a0,$a1,$e6,$a4,$a5,$e4,$a3,$e5,$a8,$a9,$aa,$ab,$ac,$ad,$ae,
$af,$ef,$e0,$e1,$e2,$e3,$a6,$a2,$ec,$eb,$a7,$e8,$ed,$e9,$e7,$ea,
$9e,$80,$81,$96,$84,$85,$94,$83,$95,$88,$89,$8a,$8b,$8c,$8d,$8e,
$8f,$9f,$90,$91,$92,$93,$86,$82,$9c,$9b,$87,$98,$9d,$99,$97,$9a);

var
KOI_2_WIN:array[$80..$FF] of byte;

procedure MakeKOITable;
var i:integer;
begin
for i:=$80 to $FF do KOI_2_WIN[i]:=DOS_2_Win[KOI_2_DOS[i]];
end;

procedure DOSToWin(var s:string);
var k,i:integer;
begin
k:=Length(s);
for i:= 1 to k do
if byte(s[i])>$7F then
s[i]:=char(DOS_2_Win[byte(s[i])]);
end;

procedure KOIToWin(var s:string);
var k,i:integer;
begin
k:=Length(s);
for i:= 1 to k do
if byte(s[i])>$7F then
s[i]:=char(KOI_2_Win[byte(s[i])]);
end;

procedure DecodeHTM(const fname:string);
// автоматич. распознавание кодировки и перекодирование в Win1251

type
TCodePage=(cpWin1251,cp866,cpKOI8R);
PMap=^TMap;
TMap=array[#$80..#$FF]of char;

function GetMap(CP:TCodePage):PMap;
{ должна возвращать указатель на таблицу перекодировки из CP в Windows1251
(nil для CP = cpWin1251) }
begin
case CP of
cpWin1251: Result:=nil;
cp866: Result:=@DOS_2_Win;
cpKOI8R: Result:=@KOI_2_WIN;
end
end;

function DetermineRussian(Buf:PChar; Count:Integer):TCodePage;
const
ModelBigrams: array [0..33, 0..33] of Byte = (
{АБВГДЕЖЗИЙКЛМHОПРСТУФХЦЧШЩЪЫЬЭЮЯ_Ё}



 
bolega   (2003-01-05 13:47) [9]

продолжение

{А}(0,20,44,12,22,23,16,60,4,9,63,93,47,110,0,16,35,61,81,1,5,13,24,17,12,4,0,0,0,0,14,31,205,1),
{Б}(19,0,0,0,4,19,0,0,8,0,2,15,1,4,41,0,15,5,0,15,0,2,1,0,0,6,16,37,0,0,0,4,3,0),
{В}(97,0,1,0,2,57,0,5,40,0,4,25,2,23,78,2,8,28,4,12,0,1,0,0,8,1,0,40,1,0,0,5,106,3),
{Г}(13,0,0,0,9,5,0,0,15,0,1,17,1,2,96,0,24,0,0,7,0,0,0,0,0,0,0,0,0,0,0,0,8,0),
{Д}(63,0,9,1,2,71,1,0,35,0,3,16,2,22,50,2,19,9,2,25,0,2,1,0,1,0,1,9,4,0,1,5,17,4),
{Е}(4,14,15,34,56,22,13,14,2,34,39,77,73,150,6,9,101,64,81,1,0,15,5,12,10,6,0,0,0,0,3,4,235,1),
{Ж}(13,0,0,0,12,47,0,0,16,0,1,0,0,23,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,2,2),
{З}(76,2,11,3,11,4,1,0,7,0,2,4,11,24,17,0,6,1,0,8,0,0,0,0,0,0,0,16,6,0,1,4,17,0),
{И}(7,9,32,5,18,60,4,42,31,27,28,46,55,49,12,7,26,60,53,0,5,25,14,28,4,1,0,0,0,0,9,56,255,0),
{Й}(0,0,0,0,2,0,0,0,0,0,1,3,0,3,0,0,0,10,3,0,0,0,0,1,1,0,0,0,0,0,0,0,122,0),
{К}(92,0,3,0,0,7,2,1,39,0,0,27,0,14,110,0,18,5,35,18,0,0,11,0,0,0,0,0,0,0,0,0,55,0),
{Л}(85,1,0,2,1,70,6,0,85,0,5,3,0,9,67,1,0,9,0,15,0,0,0,2,0,0,0,9,66,0,15,43,57,4),
{М}(44,0,0,0,0,65,0,0,47,0,1,1,10,15,57,7,0,2,0,24,0,0,0,0,0,0,0,28,0,0,0,8,109,3),
{}(139,0,0,1,11,108,0,4,152,0,7,0,1,69,161,0,0,8,25,24,5,1,5,2,0,1,0,83,10,0,1,29,38,5),
{О}(0,72,139,76,74,32,32,19,12,52,21,93,68,72,7,34,93,102,98,1,2,6,6,19,15,2,0,0,0,1,4,9,252,2),
{П}(17,0,0,0,0,43,0,0,14,0,1,9,0,1,125,3,120,1,2,8,0,0,0,0,0,0,0,3,6,0,0,3,2,2),
{Р}(151,1,6,4,3,103,7,0,76,0,4,0,11,10,117,1,0,5,9,39,2,5,0,1,3,0,0,24,7,0,1,10,22,5),
{С}(24,1,21,0,3,39,0,0,33,0,56,41,11,15,58,30,5,30,183,16,0,4,1,4,1,0,0,8,25,0,1,50,41,2),
{Т}(83,0,43,0,3,87,0,0,71,0,9,3,2,26,180,0,55,33,1,23,1,0,1,4,0,0,0,20,78,0,0,5,82,4),
{У}(3,6,7,14,19,8,13,6,0,1,13,15,10,7,0,12,17,16,19,0,1,3,0,12,5,8,0,0,0,0,22,1,65,0),
{Ф}(4,0,0,0,0,4,0,0,11,0,0,1,0,0,9,0,3,0,0,4,1,0,0,0,0,0,0,0,0,0,0,0,2,0),
{Х}(9,0,2,0,0,2,0,0,5,0,0,1,0,5,26,0,4,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,76,0),
{Ц}(5,0,0,0,0,16,0,0,48,0,1,0,0,0,4,0,0,0,0,3,0,0,0,0,0,0,0,2,0,0,0,0,3,0),
{Ч}(30,0,0,0,0,52,0,0,23,0,3,1,0,14,1,0,0,0,36,5,0,0,0,0,1,0,0,0,1,0,0,0,2,2),
{Ш}(13,0,0,0,0,28,0,0,17,0,4,4,0,4,3,0,0,0,1,3,0,0,0,0,0,0,0,0,3,0,0,0,1,1),
{Щ}(6,0,0,0,0,23,0,0,16,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1),
{Ъ}(0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0),
{Ы}(0,5,14,1,3,28,0,2,0,22,6,19,21,2,0,5,4,7,10,0,0,37,0,3,4,0,0,0,0,0,0,1,84,0),
{Ь}(0,1,0,0,0,9,0,10,1,0,13,0,2,26,0,0,0,10,3,0,0,0,1,0,6,0,0,0,0,0,6,4,117,0),
{Э}(0,0,0,0,0,0,0,0,0,0,3,3,0,0,0,0,0,0,31,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0),
{Ю}(0,5,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,1,15,0,0,0,1,4,1,15,0,0,0,0,0,0,38,0),
{Я}(0,0,9,2,7,10,3,19,0,0,1,6,7,8,0,0,2,6,19,0,0,3,5,1,0,3,0,0,0,0,5,2,177,0),
{_}(42,80,193,43,109,41,18,53,159,0,144,27,83,176,187,229,70,231,99,47,15,13,6,58,7,0,0,0,0,38,0,22,0,2),
{Ё}(0,0,0,0,3,0,0,0,0,0,2,4,4,8,0,0,5,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0));
{ "рейтинг" буквы Ё условно принимается равным 1/20 от "рейтинга" буквы E,
если сочетание с участием Ё корректно, иначе - 0 }


 
bolega   (2003-01-05 13:48) [10]

продолжение 2

type
TVariation = array [0..33, 0..33] of Integer;
var I,J,iC,iPredC,Max:integer; C:Char; CP:TCodePage; D,MinD,Factor:double;
AMap:PMap; PV:^TVariation; Vars:array[TCodePage] of TVariation;
begin
DetermineRussian:=cpWin1251; { по yмолчанию }
{ вычисление распределений биграмм }
FillChar(Vars, SizeOf(Vars), 0);
for CP:=Low(Vars) to High(Vars) do begin
AMap:=GetMap(CP);
PV:=@Vars[CP];
iPredC:=32;
for I:=0 to Count - 1 do begin
C:=Buf[I];
iC:=32;
if C >= #128 then begin
if AMap <> nil then C:=AMap^[C];
if not (C in ["Ё", "ё"]) then begin
C:=Chr(Ord(C) and not 32); { "a".."я" -> "А".."Я" }
if C in ["А".."Я"] then iC:=Ord(C) - Ord("А");
end
else iC:=33;
end;
Inc(PV^[iPredC, iC]);
iPredC:=iC;
end;
end;
{ вычисление метрики и определение наиболее правдоподобной кодировки }
MinD:=0;
for CP:=Low(Vars) to High(Vars) do begin
PV:=@Vars[CP];
PV^[32, 32]:=0;
Max:=1;
for I:=0 to 33 do
for J:=0 to 33 do
if PV^[I, J] > Max then Max:=PV^[I, J];
Factor:=255 / Max; { ноpмализация }
D:=0;
for I:=0 to 33 do
for J:=0 to 33 do
D:=D + Abs(PV^[I, J] * Factor - ModelBigrams[I, J]);
if (MinD = 0) or (D < MinD) then begin
MinD:=D;
DetermineRussian:=CP;
end;
end;
end;

const
MaxRusCntLines=10;
MaxLines=200;
var f,fn:TextFile; L:TStringList; RusCnt,Cnt,old,j:integer; p:PChar;
cp:TCodePage; s,newname:string;
begin
AssignFile(f,fname);
L:=TStringList.Create;
RusCnt:=0;
Cnt:=0;
try
Reset(f);
while not EOF(f) do begin
inc(Cnt);
// если в MaxLines не встетилось русских букв - прервем
if Cnt>MaxLines then break;
Readln(f,s);
old:=RusCnt;
// ищем русские символы
for j:=1 to Length(s) do
if byte(s[j]) in [$80..$FF] then begin
inc(RusCnt);
break
end;
if old<>RusCnt then L.Add(s);
// для анализа достаточно MaxRusCntLines строк с русскими буквами
if RusCnt=MaxRusCntLines then break
end;
CloseFile(f);
if L.Count=0 then exit; // нет строк с русскими буквами
p:=PChar(L.Text);
// определим кодировку
cp:=DetermineRussian(p,StrLen(p));
if cp=cpWin1251 then exit;
// копируем файл с одновременным перекодированием
newname:=AppDir+"temp\~2.html";
AssignFile(fn,newname);
Reset(f);
Rewrite(fn);
while not EOF(f) do begin
Readln(f,s);
if cp=cp866 then DOSToWin(s) else KOIToWin(s); // cpKOI8R
Writeln(fn,s)
end;
CloseFile(f);
CloseFile(fn);
// запишем на старое место
FileUtil.CopyFile(newname,fname,nil);
finally
L.Free;
end;
end;



Страницы: 1 вся ветка

Форум: "WinAPI";
Текущий архив: 2003.02.17;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.014 c
1-52821
MikeFW
2003-02-07 11:22
2003.02.17
Размещение файлового образа чужего EXE-файла в моем EXE-файле?


3-52769
некто2003
2003-01-29 21:42
2003.02.17
Чистое чтение таблиц


1-52847
Nikos
2003-02-07 16:04
2003.02.17
Ищу информацию по работе с реестром Windows


1-53077
shane54
2003-02-06 14:01
2003.02.17
Базовы навыки TreeView


14-53222
malkolinge
2003-01-31 14:40
2003.02.17
Ученье Свет а неученье тьма !





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский