【问题标题】:Decoding UTF-16 with PHP使用 PHP 解码 UTF-16
【发布时间】:2014-08-25 15:13:18
【问题描述】:

我偶然发现了一段用 Python 编写的有趣代码:

from struct import pack

chars = [109, 0, 97, 0, 110, 0, 105, 0, 102, 0, 101, 0, 115, 0, 116, 0]
length = 16

data = ""
for i in range(0, length):
    ch = pack("=b", chars[i])
    data += unicode(ch, errors='ignore')

    if data[-2:] == "\x00\x00":
        break

end = data.find("\x00\x00")
if end != -1:
    data = data[:end]

print(len(data.decode("utf-16", "replace"))) // outputs 8, string is 'manifest'

如您所见,Python 确实正确解码了utf-16。 但是,当我尝试将代码移植到 PHP 时,我得到了不好的结果:

$chars = array(109, 0, 97, 0, 110, 0, 105, 0, 102, 0, 101, 0, 115, 0, 116, 0);
$length = 16;

$data = "";
for ($i = 0; $i < $length; $i++) {
    $data .= pack("c", $chars[$i]);

    if (substr($data, -2) == "\x00\x00") {
        break;
    }
}

$end = strpos($data, "\x00\x00");
if ($end !== false) {
    $data = substr($data, 0, $end);
}

// md_convert_encoding() doesn't seem to work
printf(strlen($data)); // outputs 16

我看到的唯一解决方案是放弃 UTF 魔法并将循环更改为:

for ($i = 0; $i < $length; $i+=2)

对此我有什么办法吗,还是只使用修改后的 for 循环?

谢谢。

【问题讨论】:

  • “解码 UTF-16”到什么到底是什么?
  • 您的主要问题是utf8_encode 远不及unicode 在Python 中的作用。
  • @deceze:是的,我在某个时候注意到了这一点,但它似乎已经过去了;我会删除它。
  • 回答我自己的问题三个 cmets:您的问题应该是 “将整数数组解释为 UTF-16 编码字节并将其转换为 UTF-8 编码字符串”...

标签: php character-encoding utf-16


【解决方案1】:

首先看看How can I convert array of bytes to a string in PHP?

使用该解决方案,您可以将字节数组转换为类似的字符串

$chars = array(109, 0, 97, 0, 110, 0, 105, 0, 102, 0, 101, 0, 115, 0, 116, 0);
$str = call_user_func_array("pack", array_merge(array("C*"), $chars));
$convertedStr = iconv('utf-16', 'utf-8', $str);

var_dump($str);
var_dump($convertedStr);

执行此脚本输出

string(16) "manifest"
string(8) "manifest"

【讨论】:

  • 啊,iconv 似乎做得更好!顺便问一下,'C*' 和 'c' 之间有什么明显的区别吗?
  • 您需要星号,否则只会打包第一个字符。在这种情况下,您使用 'c' 还是 'C' 没有区别,因为所有数字都小于 127,因此适合有符号和无符号字符字节。
猜你喜欢
  • 2020-08-02
  • 2014-04-22
  • 2019-05-23
  • 2019-02-25
  • 1970-01-01
  • 2010-12-27
  • 2012-06-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多