【问题标题】:How this works: chr(($number >>6 )+192).chr(($number & 63)+128);这是如何工作的: chr(($number >>6 )+192).chr(($number & 63)+128);
【发布时间】:2013-01-23 14:43:14
【问题描述】:

能否请您解释一下这行代码如何等效于下一个代码:

<?php
$string = chr( ( $number >> 6 ) + 192 ).chr( ( $number & 63 ) + 128 );
?>

相当于:

if ( $number >=128 && $number <=2047 ){

   $byte1 = 192 + (int)($number / 64); //= 192 + ( $number >> 6 )
   $byte2 = 128 + ($number % 64);      //= 128 + ( $number & 63 )
   $utf = chr($byte1).chr($byte2);
 }

例如输入数字 1989 都会产生 ߅

这些代码用于将 UNICODE 实体转换回原始 UTF-8 字符。

【问题讨论】:

  • 在 Wikipedia 上查找 UTF-8 编码。他们对它的工作原理进行了详尽的描述。一旦你理解了编码,这段代码就非常简单了。
  • 问题是如何 (int)($number / 64) =? ( $number >> 6 )

标签: php utf-8 multibyte chr


【解决方案1】:

上面的代码使用二元运算符。 &gt;&gt; 是右移运算符。它将数字中的位向右移动(朝向更重要的位)。

所以11110000 &gt;&gt; 2 = 00111100

相当于除以2的幂 $number &gt;&gt; $n$number / pow(2,$n) 相同。

&amp; 是“位与”运算符。它比较两个数字上的相应位,并将结果设置为两个数字中的 1

11110000 &amp; 01010101 = 01010000

$number 与 63 (001111111) 相乘,得到 $number 除以 64(也称为模数)的余数,即为 $number % 64

【讨论】:

    【解决方案2】:

    $number &gt;&gt; 6 是二进制右移操作,即:11000000 &gt;&gt; 6 == 00000011 等价于 $number / pow(2,6) aka $number / 64

    $number &amp; 63 是二进制 AND00111111

    作为二元运算,两者的执行速度要快得多,因为它们都处理一两个幂。

    【讨论】:

      【解决方案3】:

      在@Mchl 的答案中添加 UTF 序列中添加 192 的原因是表示字节信息的开始

      192 - 11000000 - 2 字节序列的开始 (128 + 64)

      224 - 11100000 - 3 字节序列的开始(128 + 64 + 32)

      240 - 11110000 - 4 字节序列的开始(128 + 64 + 32 + 16)

      248 - 11111000 - 5 字节序列的开始(受限)(... + 8)

      252 - 11111100 - 6 字节序列的开始(受限)(... + 4)

      254 - 11111110 - 无效

      表参考:https://en.wikipedia.org/w/index.php?title=UTF-8&oldid=388157043

      UTF-8 byte range table

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-12
        • 2015-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-05
        • 2014-04-26
        相关资源
        最近更新 更多