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

Вниз

UTF-8   Найти похожие ветки 

 
ford ©   (2009-11-27 13:27) [0]

Здравствуйте!
как на дельфи автоматически определить, что текст в кодировке UTF-8 ?
в инете нашел что есть такая славная функция
как function DetectUTF8Encoding(const s : UTF8String): TEncodeType;
в модуле WideStrUtils.pas

но в своем Delphi 7
я такого модуля не нашел :(


 
Игорь Шевченко ©   (2009-11-27 13:36) [1]


> как на дельфи автоматически определить, что текст в кодировке
> UTF-8


никак


 
ford ©   (2009-11-27 13:47) [2]

ну почему никак ....
я вот написал такую функцию
Function UTF8Check(src:TStrings):Boolean;
var i,j,RCount,ACount:Integer;
   s:String;
Begin
RCount:=0; ACount:=0;
for i:=0 to src.Count-1 do
 Begin
  s:=src[i];
  for j:=1 to Length(s) do
   Begin
    Inc(ACount);
    if (Ord(s[j])>=192) and (Ord(s[j])<=255) Then Inc(RCount);
   End;
 end;
if ((rCount*100)/acount)<20 Then result:=true
Else result:=false;
End;


в принципе определяется что там UTF8
хотя конечно это не 100%
но работает

а вот подскажите, я поставил менее 20% должны встречаться русские букавки :) честно, поставил от балды, может кто подскажет какой процент наличия русских букв относительно всего текста может с более менее нормальной долей вероятности сказать что этот текст в utf8 ?
понятно что моя функция на тексте
"privet vasya" выдаст что это UTF8 :( может что то еще нужно проверять не просто что это английские буквы а еще и что много "P" и "?" ?


 
clickmaker ©   (2009-11-27 13:49) [3]

на паскаль сам переводи

BOOL IsUTF8(LPBYTE pbBuff, LONG cb)
{
BOOL fASCII;
int i, nb, curr;
BYTE b;

BOOL result = FALSE;
if (cb == 0) return result;

fASCII = TRUE;
curr = 0;
while (curr < cb)
{
 nb = 0;
 b = pbBuff[curr];
 if ((b & 0x80) != 0)
 {
  fASCII = FALSE;
  if ((b & 0xc0) == 0x80) return result;
  else if ((b & 0xe0) == 0xc0) nb = 1;
  else if ((b & 0xf0) == 0xe0) nb = 2;
  else if ((b & 0xf8) == 0xf0) nb = 3;
  else if ((b & 0xfc) == 0xf8) nb = 4;
  else if ((b & 0xfe) == 0xfc) nb = 5;
  else return result;

  if (curr + nb >= cb) return result;

  for (i = 1; i <= nb; i++)
  {
   if ((pbBuff[i + curr] & 0xC0) != 0x80) return result;
  }
 }
 curr += nb + 1;
}
result = !fASCII;
return result;
}


 
ford ©   (2009-11-27 14:10) [4]

а пояснить логику можно??


 
Медвежонок Пятачок ©   (2009-11-27 14:17) [5]

Решение в лоб.

var s : string;
begin
s := "мама мыла раму";
//s := AnsiToUtf8(s);
if AnsiToUtf8(Utf8ToAnsi(s)) <> s then ShowMessage("Либо не в утф, либо нет не-анси символов")


 
clickmaker ©   (2009-11-27 14:31) [6]

> [4] ford ©   (27.11.09 14:10)
> а пояснить логику можно??

логика там несложная.
в утф-8 каждый символ может занимать от 1 до 6 байт. Если значение байта лежит за пределами кодировки ascii ((b & 0x80) != 0), то проверяем значение на совпадение с некими масками, которые с достаточной долей вероятности говорят о том, что это утф.
При этом в каждом байте также установлены биты, которые говорят, что этот байт не является последним (nb = 1...nb = 5).


 
ford ©   (2009-11-27 16:04) [7]


> Решение в лоб.

прикольное решение
для больших текстов не подходит но для маленьких вполне :)


> clickmaker ©   (27.11.09 14:31) [6]


спасибо, теперь понятно что там делается :)


 
Омлет ©   (2009-11-30 18:20) [8]

> [7] ford ©   (27.11.09 16:04)
> для больших текстов не подходит но для маленьких вполне

Бери маленький кусок большого текста.


 
Евгений471   (2009-12-14 11:37) [9]


> while (curr < cb) {  nb = 0;  b = pbBuff[curr];  if ((b
> & 0x80) != 0)  {   fASCII = FALSE;   if ((b & 0xc0) == 0x80)
> return result;   else if ((b & 0xe0) == 0xc0) nb = 1;   else
> if ((b & 0xf0) == 0xe0) nb = 2;   else if ((b & 0xf8) ==
> 0xf0) nb = 3;   else if ((b & 0xfc) == 0xf8) nb = 4;   else
> if ((b & 0xfe) == 0xfc) nb = 5;   else return result;   if
> (curr + nb >= cb) return result;   for (i = 1; i <= nb;
> i++)   {    if ((pbBuff[i + curr] & 0xC0) != 0x80) return
> result;   }  }  curr += nb + 1; } result = !fASCII;


на pascal

function TEncodeClass.FromString(const index: integer;
 const s: string): char;
begin
if (index <= 0) or (index > length(s)) then
begin
 Result := #0;
 exit;
end;
Result := s[index];
end;

function TEncodeClass.IsUtf8(const s: string; const cb:cardinal): boolean;
var
 fASCII:boolean;
 i, nb, curr:integer;
 b:byte;
begin
Result := false;
if cb<=0 then exit;
fASCII := TRUE;
curr   := 1;
while (curr < cb) do
begin          
 nb := 0;
 b  :=  ord(FromString(curr,s));
 if (b and StrToInt64("0x80")) <> 0 then
 begin
  fASCII := FALSE;
  if (b and StrToInt64("0xc0")) = StrToInt64("0x80") then exit else
  if (b and StrToInt64("0xe0")) = StrToInt64("0xc0") then nb := 1 else
  if (b and StrToInt64("0xf0")) = StrToInt64("0xe0") then nb := 2 else
  if (b and StrToInt64("0xf8")) = StrToInt64("0xf0") then nb := 3 else
  if (b and StrToInt64("0xfc")) = StrToInt64("0xf8") then nb := 4 else
  if (b and StrToInt64("0xfe")) = StrToInt64("0xfc") then nb := 5 else exit;
  if curr + nb >= cb then exit;
  for i := 1 to nb do
  if (ord(FromString(i+curr,s)) and StrToInt64("0xC0")) <> StrToInt64("0x80") then exit;
 end;
 inc(curr,nb+1);
end;
Result := not fASCII;
end;


 
clickmaker ©   (2009-12-14 11:43) [10]

> (b and StrToInt64("0xc0")) = StrToInt64("0x80")

что это??


 
Евгений471   (2009-12-14 14:57) [11]


> > (b and StrToInt64("0xc0")) = StrToInt64("0x80")что это?
> ?

> StrToInt64("0x80")
числа в 16-ти ричной системе - коды символов.
просто перевел код с C  на pascal без изминений, лень было писать коды символов в оригенальном значении.

вот этот код:

BOOL IsUTF8(LPBYTE pbBuff, LONG cb)
{
BOOL fASCII;
int i, nb, curr;
BYTE b;

BOOL result = FALSE;
if (cb == 0) return result;

fASCII = TRUE;
curr = 0;
while (curr < cb)
{
nb = 0;
b = pbBuff[curr];
if ((b & 0x80) != 0)
{
 fASCII = FALSE;
 if ((b & 0xc0) == 0x80) return result;
 else if ((b & 0xe0) == 0xc0) nb = 1;
 else if ((b & 0xf0) == 0xe0) nb = 2;
 else if ((b & 0xf8) == 0xf0) nb = 3;
 else if ((b & 0xfc) == 0xf8) nb = 4;
 else if ((b & 0xfe) == 0xfc) nb = 5;
 else return result;

 if (curr + nb >= cb) return result;

 for (i = 1; i <= nb; i++)
 {
  if ((pbBuff[i + curr] & 0xC0) != 0x80) return result;
 }
}
curr += nb + 1;
}
result = !fASCII;
return result;
}


 
clickmaker ©   (2009-12-14 15:20) [12]

лень писать $80 вместо StrToInt64("0x80") ?


 
Евгений471   (2009-12-14 17:24) [13]


> лень писать $80 вместо StrToInt64("0x80") ?

яж указал, как есть в исходном - так и написал, кого не устроит вариант - поправить недолго.



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

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

Наверх




Память: 0.48 MB
Время: 0.005 c
15-1260088479
Clone
2009-12-06 11:34
2010.02.14
хп на ноут


15-1259789497
Игорь Шевченко
2009-12-03 00:31
2010.02.14
Линукс тоже дырки закрывает


15-1260119366
Cerberus
2009-12-06 20:09
2010.02.14
Какую СУБД выбрать?


2-1260808991
alexan
2009-12-14 19:43
2010.02.14
Вопрос по Delphi


1-1237817783
Дмитрий Белькевич
2009-03-23 17:16
2010.02.14
SHBrowseForFolder открывается пустым





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский