使用PHP解码UTF-16

3

我发现了一段有趣的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)

这个问题我能做些什么呢?或者只能使用修改后的循环吗?

谢谢。


“Decode UTF-16” 要解码成什么? - deceze
你的主要问题是utf8_encode与Python中的unicode完全不同。 - deceze
@deceze:是的,我也注意到了,但似乎已经被忽略了;我会将其删除。 - Vanity
回答我自己之前的问题:你的问题应该是“将整数数组解释为UTF-16编码字节并将其转换为UTF-8编码字符串”。 - deceze
1个回答

2
首先看一下如何在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”之间是否有明显的区别? - Vanity
你需要使用星号,否则只有第一个字符会被打包。在这种情况下,无论你使用 'c' 还是 'C' 都没有区别,因为所有的数字都小于 127,因此适合于有符号和无符号字符字节。 - ragol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接