convert UTF-8 to cp1251

kvn

programmer
convert UTF-8 to cp1251

Вопрос:
Есть ли конвертер на PHP, который можно применить для преобразования строки из UTF-8 в текстовую строку (например в cp1251). Текст именно в UTF-8, а не в UTF-HTML-entities...

Для преобразования cp1251->UTF-8 использую ф-цию:

PHP:
function win2utf($str)
{
  $utf = "";
  for($i = 0; $i < strlen($str); $i++)
  {
    $donotrecode = false;
    $c = ord(substr($str, $i, 1));
    if ($c == 0xA8) $res = 0xD081;
    elseif ($c == 0xB8) $res = 0xD191;
    elseif ($c < 0xC0) $donotrecode = true;
    elseif ($c < 0xF0) $res = $c + 0xCFD0;
    else $res = $c + 0xD090;
    $utf .= ($donotrecode) ? chr($c) : (chr($res >> 8) . chr($res & 0xff));
  }
  return $utf;
}
все нормально работает, только не могу сообразить обратную операцию...

Заранее спасибо.

П.С. iconv не предлагать.
 

tony2001

TeaM PHPClub
kvn
не густо что? =)
чем готовый рабочий алгоритм не подошел?
 

kvn

programmer
все гуд!
Спасибо Тони!

П.С. Хотя с первыми байтами 0xEF 0xBB 0xBF
я так и не разобрался....

Пока я из просто проскипал, чуть позже разбирусь..
поидее они указывают charset and byte order...
 

kvn

programmer
Функция _тупо_ переписанная с дифф-а, так что кому нужно, тот оптимизирует...

Нате:

PHP:
<?php
$__src_win_utf8 = array(
128,129,130,131,132,133,134,135,136,137,138,139,140,141,
142,143,144,145,146,147,148,149,150,151,153,154,155,156,
157,158,159,160,161,162,163,164,165,166,167,168,169,170,
171,172,173,174,175,176,177,178,179,180,181,182,183,184,
185,186,187,188,189,190,191,192,193,194,195,196,197,198,
199,200,201,202,203,204,205,206,207,208,209,210,211,212,
213,214,215,216,217,218,219,220,221,222,223,224,225,226,
227,228,229,230,231,232,233,234,235,236,237,238,239,240,
241,242,243,244,245,246,247,248,249,250,251,252,253,254,
255,32);

$__win_utf8 = array(
1026,1027,8218,1107,8222,8230,8224,8225,8364,8240,1033,8249,
1034,1036,1035,1039,1106,8216,8217,8220,8221,8226,8211,8212,
8482,1113,8250,1114,1116,1115,1119,160,1038,1118,1032,164,
1168,166,167,1025,169,1028,171,172,173,174,1031,176,177,1030,
1110,1169,181,182,183,1105,8470,1108,187,1112,1029,1109,1111,
1040,1041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,
1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,
1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,
1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,
1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,
1100,1101,1102,1103,32);

function utf8cp1251($s, $from, $to) {
    $len = strlen($s);
    $pos = 0;
    $newlen = 0;
    $ret = '';

    while ($pos<$len) {
         if (ord($s[$pos]) < 0x80) {
            $ret .= $s[$pos];
            $pos++;
        } else {
            if ( ((ord($s[$pos]) & 0xE0) == 0xC0) && ($pos < ($len-1)) ) {
                $c = ( (ord($s[$pos]) & 0x1F) << 6 ) + ( ord($s[$pos+1]) & 0x3F)
;
                $pos+=2;
            } elseif ( ((ord($s[$pos]) & 0xF0) == 0xE0) && ($pos<($len-2))) {
                $c = (((ord($s[$pos])) & 0x0F) << 12) + ((ord($s[$pos+1]) & 0x3F
) << 6) + (ord($s[$pos+2]) & 0x3F);
                $pos+=3;

            } else {
                $c = 0;
                $pos+=4;
            }
            for ($i=0; $i<128; $i++) {
                if ($c == $from[$i]) {
                    $c = $to[$i];
                    break;
                }
            }
            $ret .= chr($c);
        }
    }
    if ((ord($s[0]) == 0xEF)) {
        $ret = substr($ret, 1, strlen($ret));
    }
    return $ret;


}


// Example of Use
// utf8.txt - file saved from NotePad in UTF-8 encoding.

$file = "utf8.txt";

$str = join("", file($file));

echo "UTF: ".$str;
$to_table_utf8 = $__src_win_utf8;
$from_table_utf8 = $__win_utf8;


$str2 =  utf8cp1251($str, $from_table_utf8, $to_table_utf8);

echo "CP: ".$str2;
?>
have fun.
 

XtremallyPurpur

Новичок
Из комментов в мане:
PHP:
  function utf8win1251($s){
    $out = $c1 = "";
    $byte2=false;
    for ($c=0;$c<strlen($s);$c++){
      $i=ord($s[$c]);
      if ($i<=127) $out.=$s[$c];
      if ($byte2){
        $new_c2=($c1&3)*64+($i&63);
        $new_c1=($c1>>2)&5;
        $new_i=$new_c1*256+$new_c2;
        if ($new_i==1025){
          $out_i=168;
        }
        else{
          if ($new_i==1105){
            $out_i=184;
          }
          else {
            $out_i=$new_i-848;
          }
        }
      $out.=chr($out_i);
      $byte2=false;
      }
      if (($i>>5)==6) {
        $c1=$i;
        $byte2=true;
      }
    }
    return $out;
  }
 

anisimov_sasha

Guest
что Вы делаете...

$xmlFile = mb_convert_encoding($xmlFile, "windows-1251", "UTF-8");

думаю ничего нет непонятного
 

Orlis

Guest
зачем изобретать велосипед?

$string = htmlentities($string, ENT_NOQUOTES, 'UTF-8');
$string = html_entity_decode($string, ENT_NOQUOTES, 'Windows-1251');
 

anight

Новичок
Orlis
digger !

а почему у меня ничего не работает ?

Код:
> cat test.php
<?
        $string = `echo "привет" | iconv -f koi8-r -t utf-8`;
        echo $string;
        $string = htmlentities($string, ENT_NOQUOTES, 'UTF-8');
        echo $string;
        $string = html_entity_decode($string, ENT_NOQUOTES, 'Windows-1251');
        echo $string;
?>
> php -f test.php
п©я&#9472;п&#9574;п&#9569;п&#9571;я&#9484;
п©я&#9472;п&#9574;п&#9569;п&#9571;я&#9484;
п©я&#9472;п&#9574;п&#9569;п&#9571;я&#9484;
> php -v
PHP 4.3.7 (cgi) (built: Jun 21 2004 17:06:51)
Copyright (c) 1997-2004 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies
 

voituk

прозревший
Такая штука проходит "на ура"
PHP:
iconv("UTF-8", "Windows-1251", "This is a test.");
 

fixxxer

К.О.
Партнер клуба
Не сомневаюсь, что для строки "This is a test" все проходит нормально. :D
 

voituk

прозревший
для строки "привет это тест!" тоже всё проходит нормально.
 

LSD^

Новичок
У меня в мускле 4 данные в UTF-8, есть строка в верхнем регистре, мне ее нужно в нижний. Мускльем не получается, хотя вроде ему нужно чарсет по умолчанию поставить тоже UTF-8, но это напрягает и я не пробовал.

Подскажите.. мож кто-то сталкавался.
 
Сверху