这个问题与我以前的问题有关:
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字符串是否有良好的做法?
答案 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"
]
}