Bir utf-8 dize belirli bir karakter için kod noktası numarası almak nasıl?

5 Cevap php

Ben belirli bir UTF-8 dizesi için UCS-2 kod puan almak istiyoruz. Örneğin kelime "merhaba" "0068 0065 006C 006C 006F" gibi bir şey olmalıdır. Karakterleri Doğu Asya dilleri gibi karmaşık komut dahil olmak üzere herhangi bir dilden olabileceğini unutmayın.

Yani, sorun "UCS-2 kod noktasına belirli bir karakter dönüştürmek" için aşağı gelir

Ama nasıl? Ben büyük bir acele olduğum, her türlü yardım çok çok çok takdir duyarız.

Şimdiden teşekkürler


Transcription of questioner's response posted as an answer

Cevabınız için teşekkürler, ancak PHP v 4 veya 5 yapılabilir ama değil 6 gerekiyor.

Dize bir form alanına gelen, bir kullanıcı giriş olacaktır.

Ben gibi utf8to16 veya utf8decode bir PHP sürümü uygulamak istiyorum

function get_ucs2_codepoint($char)
{
    // calculation of ucs2 codepoint value and assign it to $hex_codepoint
    return $hex_codepoint;
}

PHP ile bana yardımcı olabilir veya sürüm yukarıdaki ile PHP ile yapılabilir?

Tekrar teşekkür ederim.

5 Cevap

Scott Reynen convert UTF-8 into Unicode bir fonksiyon yazdım. Ben PHP documentation bakarak bulundu.

function utf8_to_unicode( $str ) {

    $unicode = array();        
    $values = array();
    $lookingFor = 1;

    for ($i = 0; $i < strlen( $str ); $i++ ) {
        $thisValue = ord( $str[ $i ] );
    if ( $thisValue < ord('A') ) {
        // exclude 0-9
        if ($thisValue >= ord('0') && $thisValue <= ord('9')) {
             // number
             $unicode[] = chr($thisValue);
        }
        else {
             $unicode[] = '%'.dechex($thisValue);
        }
    } else {
          if ( $thisValue < 128) 
        $unicode[] = $str[ $i ];
          else {
                if ( count( $values ) == 0 ) $lookingFor = ( $thisValue < 224 ) ? 2 : 3;                
                $values[] = $thisValue;                
                if ( count( $values ) == $lookingFor ) {
                    $number = ( $lookingFor == 3 ) ?
                        ( ( $values[0] % 16 ) * 4096 ) + ( ( $values[1] % 64 ) * 64 ) + ( $values[2] % 64 ):
                        ( ( $values[0] % 32 ) * 64 ) + ( $values[1] % 64 );
            $number = dechex($number);
            $unicode[] = (strlen($number)==3)?"%u0".$number:"%u".$number;
                    $values = array();
                    $lookingFor = 1;
          } // if
        } // if
    }
    } // for
    return implode("",$unicode);

} // utf8_to_unicode

Varolan gibi iconv olarak yarar, ya da her ne kütüphaneler kullandığınız dil ile gelir kullanın.

Kendi çözüm haddeleme ısrar ederse, UTF-8 formatında okumak. Temel olarak, her bir kod noktası kod noktası değerine bağlı olarak, 1-4 bayt olarak depolanır. Aşağıdaki gibi aşağıdaki gibidir:

  • U 0000 - U 007 F: 1 byte: 0xxxxxxx
  • U 0080 - U 07 FF: 2 byte: 110xxxxx 10xxxxxx
  • U 0800 - U + FFFF: 3 byte: 1110xxxx 10xxxxxx 10xxxxxx
  • U 10000 - U +10 FFFF: 4 byte: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

Her bir x, bir veri bit olduğu. Böylece, ilk byte bakarak her kod noktası oluşturan kaç bayt söyleyebilir: Bir 0 ile başlıyorsa eğer, bu bir 1-bayt karakter. Bu 110 ile başlıyorsa, bu bir 2-bayt karakter. O 1110 ile başlıyorsa, bu 3-bayt karakter. Bunun 11.110 ile başlıyorsa, bu 4-bayt karakter. Bu 10 ile başlıyorsa, bir çokbaytlı karakteri olmayan bir başlangıç ​​bayt bulunuyor. Bunun 11.111 ile başlar, geçersiz bir karakter.

Eğer karakter kaç bayt anlamaya, bunun sadece bir zaman meselesi biraz twiddling durumunda bulunuyor. Ayrıca UCS-2 U + FFFF yukarıdaki karakterleri temsil edemez unutmayın.

Eğer bir dil belirtmek vermedi beri, burada (hata denetimi ihmal) bazı örnek C kodu:

wchar_t utf8_char_to_ucs2(const unsigned char *utf8)
{
  if(!(utf8[0] & 0x80))      // 0xxxxxxx
    return (wchar_t)utf8[0];
  else if((utf8[0] & 0xE0) == 0xC0)  // 110xxxxx
    return (wchar_t)(((utf8[0] & 0x1F) << 6) | (utf8[1] & 0x3F));
  else if((utf8[0] & 0xF0) == 0xE0)  // 1110xxxx
    return (wchar_t)(((utf8[0] & 0x0F) << 12) | ((utf8[1] & 0x3F) << 6) | (utf8[2] & 0x3F));
  else
    return ERROR;  // uh-oh, UCS-2 can't handle code points this high
}

Ben sadece bir final sınavında öğrencilere bu sorunu verdi, çünkü ben eğlenerek değilim. Burada UTF-8 bir kroki bulunuyor:

hex         binary                   UTF-8 binary
0000-007F   00000000 0abcdefg   =>   0abcdefg
0080-07FF   00000abc defghijk   =>   110abcde 10fghijk
0800-FFFF   abcdefgh ijklmnop   =>   1110abcd 10efghij 10klmnop

Ve burada bazı C99 kod:

static void check(char c) {
  if ((c & 0xc0) != 0xc0) RAISE(Bad_UTF8);
}

uint16_t Utf8_decode(char **p) { // return code point and advance *p
  char *s = *p;
  if ((s[0] & 0x80) == 0) {
    (*p)++;
    return s[0];
  } else if ((s[0] & 0x40) == 0) {
    RAISE (Bad_UTF8);
    return ~0; // prevent compiler warning
  } else if ((s[0] & 0x20) == 0) {
    if ((s[0] & 0xf0) != 0xe0) RAISE (Bad_UTF8);
    check(s[1]); check(s[2]);
    (*p) += 3;
    return ((s[0] & 0x0f) << 12)
         + ((s[1] & 0x3f) <<  6)
         + ((s[2] & 0x3f));
  } else {
    check(s[1]);
    (*p) += 2;
    return ((s[0] & 0x1f) << 6)
         + ((s[1] & 0x3f));
  }
}

PHP kodu (geçerli utf-8 varsayar ki, geçerli olmayan utf-8 için onay):

function ord_utf8($c) {
    $b0 = ord($c[0]);
    if ( $b0 < 0x10 ) {
        return $b0;
        }
    $b1 = ord($c[1]);
    if ( $b0 < 0xE0 ) {
        return (($b0 & 0x1F) << 6) + ($b1 & 0x3F);
        }
    return (($b0 & 0x0F) << 12) + (($b1 & 0x3F) << 6) + (ord($c[2]) & 0x3F);
    }

Eğer C kullanıyorsanız, o zaman mbstowcs işlevini deneyin. Bu UCS2 için utf8 dönüştürmek gerekir.

http://www.opengroup.org/onlinepubs/009695399/functions/mbstowcs.html