从json字符串解码时保留内容代码页的最佳做法是什么?

时间:2017-09-06 17:29:11

标签: perl unicode encoding utf-8

这个问题与我以前的问题有关:

What is the encoding of b2 e2 ca d4?

What is the encoding of e6 b5 8b e8 af 95

我在将一个jsong字符串解码为perl中的json对象时遇到了问题。 json字符串有中文字符测试,我认为它是用UTF-8编码的(带有八进制代码E6 B5 8B E8 AF 95),以及一些非UTF-8编码的非ascii字符(带八进制代码) b2 e2 ca d4)。

任务是将json字符串解码为json对象,持久保存正确的编码。我发现通过使用JSON->new->utf8->decode(),我们能够正确解码测试(如果json字符串不包含任何非utf-8编码的内容)。

但如果json字符串包含非utf-8编码的字符JSON parsing error: malformed UTF-8 character in JSON string, at character offset 255 (before "\x{a2294}\x{2294}","...") at...,则解码会返回错误。

这是预期的,因为字符串(其八进制代码为b2 e2 ca d4)不是utf-8编码的。但如果使用JSON->new->decode()解码结果不正确,则测试会变为其他内容,因为我看到八进制代码变为C3 A6 C2 B5 C2 8B C3 A8 C2 AF C2 95而不是原始E6 B5 8B E8 AF 95

如果字符串在其内容中包含不同的编码,我是否可以知道解码保留原始编码的json字符串是否有良好的做法?

1 个答案:

答案 0 :(得分:3)

听起来您正在尝试使用JSON来传输二进制数据,但它并不适合这种情况。我会对二进制数据进行base64编码。

use strict;
use warnings;
use feature qw( say );
use utf8;

use Encode       qw( encode );
use JSON::XS     qw( encode_json );
use MIME::Base64 qw( encode_base64 );

binmode STDOUT;

my $mime_doc1 = encode('iso-latin-1', <<'__EOS__');
Content-Type: text/plain; charset=iso-latin-1

Éric
__EOS__

my $mime_doc2 = encode('UTF-8', <<'__EOS__');
Content-Type: text/plain; charset=UTF-8

测试
__EOS__

my @encoded_docs = map { encode_base64($_, '') }
   $mime_doc1,
   $mime_doc2;

my $json_utf8 = encode_json({
   title => '♡',
   docs  => \@encoded_docs,
});

say $json_utf8;

输出(添加了空格):

{
   "title": "♡",
   "docs": [
      "Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PWlzby1sYXRpbi0xCgrJcmljCg==",
      "Q29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0PVVURi04CgrmtYvor5UK"
   ]
}