解码Unicode转义序列时出现意外结果

时间:2018-05-23 21:35:05

标签: php unicode encoding utf-8

我有一个黑色的盒子,它会喷出一个JSON,这个文件带有我认为,是转义的Unicode字符。这是一个片段:

{
    "AR_DESCRI":"LIMA CENTIMETRADA\/FORMAS U\u00c3\u2018AS 100\/180 MANI."
}

现在,以下是生成的JSON实际上应该如何与任何合理的人类相似:

{
    "AR_DESCRI":"LIMA CENTIMETRADA/FORMAS UÑAS 100/180 MANI."
}

最重要的是\u00c3\u2018应该等于Ñ字符。

但是,您可以从任何Unicode转义序列解码器检查,但情况并非如此,\u00c3\u2018的输出实际上是Ñ,这基本上是随机噪音。

我尝试了一些online decoders,我也使用了json_decode() PHP函数,这是我目前正在研究的环境。两者都给我相同的结果。如果你很好奇,这里是代码片段:

<?php
$json = '{"AR_DESCRI":"LIMA CENTIMETRADA\/FORMAS U\u00c3\u2018AS 100\/180 MANI."}';
print_r(json_decode($json));

//Output: stdClass Object ( [AR_DESCRI] => LIMA CENTIMETRADA/FORMAS UÑAS 100/180 MANI. )

所以我的问题是,为什么会发生这种情况,这是黑盒子上的编码问题吗?我使用了错误的功能吗?

提前致谢。

1 个答案:

答案 0 :(得分:1)

ÑU+00D1在UTF8中表示为文字字节\xc3\x91

由于错误地强制输入字符串上的cp1252到UTF转换而导致Mojibake的错误导致cp1252 \xc3Ã \x91\u00c3\u2018。 [左单引号]

然后将这些转换为与您看到的function ordify($str) { return implode(' ', array_map( function($a){return sprintf('U+%04x', mb_ord($a));}, preg_split('//u', $str, null, PREG_SPLIT_NO_EMPTY) )); } $borked = 'Ñ'; $fixed = mb_convert_encoding($borked, 'cp1252', 'utf-8'); var_dump( $borked, ordify($borked), $fixed, ordify($fixed) ); 的UTF等效转义。

证明:

string(5) "Ñ"
string(13) "U+00c3 U+2018"
string(2) "Ñ"
string(6) "U+00d1"

输出:

<#@ assembly name="$(SolutionDir)Project.CodeGen\bin\Debug\netcoreapp2.0\Project.CodeGen.dll" #>
<#@ import namespace="Project.CodeGen" #>

所以去修复生成你的JSON的东西,因为任何合理的人应该首先在bandaid解决方案中通过kludging生成有效数据。