perl - 将字符串转换为 is0-8859-1,以 base64 格式保存到数据库,但解码后结果为 utf8

标签 perl utf-8

我真的很困惑这个!所以这就是正在发生的事情。我使用 MIME::Base64 将 hashref 加密为字符串,使用:

encode_base64(JSON::XS->new->latin1->encode($vars))

$vars 中的变量之一称为 comment ...因此 $vars->{comment}

当我从数据库中获取文本时,内容是:

eyJwaG9uZSI6InNkZnNkZnNmZCIsImNvbW1lbnRzIjoi7fPpIHRlc3QgYWNjZW50cyB4eHh4eCIs
InJvb21zIjpbeyJkZXBvc2l0X2NhbmNlbF9wZXJpb2RfdGVybXMiOiJE6XD0dCByZXF1aXM6IDEw
JTxicj5cblx0XHRcdFx0XHRcdFx0ICBQ6XJpb2RlIGQnYW5udWxhdGlvbjogNiBtb2lzIiwiYnJl
YWtmYXN0X2F2YWlsYWJsZSI6MSwidXNlcl9pZF9mayI6ImFuZHkxIiwicm9vbV9uYW1lX3Nob3ci
OiJDaGFtYnJlIGJsZXUg7fPpIC8gQ2hhbWJyZSBEb3VibGUiLCJwZW9wbGUiOiIyIiwiYnJlYWtm
YXN0X3ByaWNlIjowLCJkZXBvc2l0X3BlcmNlbnRhZ2UiOiIxMCIsInByaWNlIjo3NSwiZGVwb3Np
dF9jYW5jZWxfcGVyaW9kIjoiMTgwIiwicm9vbV9pZCI6IjIyMiIsImRlcG9zaXRfY2FuY2VsX3Bl
cmlvZF9jYW50IjoxLCJkZXBvc2l0IjoiNy41MCJ9XSwidG90YWxfZHVlIjoiNzUuMDAiLCJlbWFp
bCI6ImFuZHkubmV3YnlAZ21haWwuY29tIiwicmVtYWluaW5nX2R1ZSI6IjY3LjUwIiwibnVtX3Bl
b3BsZSI6MiwidG8iOiIyMDE3MDQwMSIsImZyb20iOiIyMDE3MDMzMSIsImRlcG9zaXQiOiI3LjUw
In0=

在 Base64 上执行 Devel::Peek::Dump,标志看起来很完美:

SV = PV(0x2e419b8) at 0x1eece38
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x2eeaf70 "eyJwaG9uZSI6InNkZnNkZnNmZCIsImNvbW1lbnRzIjoi7fPpIHRlc3QgYWNjZW50cyB4eHh4eCIs\nInJvb21zIjpbeyJkZXBvc2l0X2NhbmNlbF9wZXJpb2RfdGVybXMiOiJE6XD0dCByZXF1aXM6IDEw\nJTxicj5cblx0XHRcdFx0XHRcdFx0ICBQ6XJpb2RlIGQnYW5udWxhdGlvbjogNiBtb2lzIiwiYnJl\nYWtmYXN0X2F2YWlsYWJsZSI6MSwidXNlcl9pZF9mayI6ImFuZHkxIiwicm9vbV9uYW1lX3Nob3ci\nOiJDaGFtYnJlIGJsZXUg7fPpIC8gQ2hhbWJyZSBEb3VibGUiLCJwZW9wbGUiOiIyIiwiYnJlYWtm\nYXN0X3ByaWNlIjowLCJkZXBvc2l0X3BlcmNlbnRhZ2UiOiIxMCIsInByaWNlIjo3NSwiZGVwb3Np\ndF9jYW5jZWxfcGVyaW9kIjoiMTgwIiwicm9vbV9pZCI6IjIyMiIsImRlcG9zaXRfY2FuY2VsX3Bl\ncmlvZF9jYW50IjoxLCJkZXBvc2l0IjoiNy41MCJ9XSwidG90YWxfZHVlIjoiNzUuMDAiLCJlbWFp\nbCI6ImFuZHkubmV3YnlAZ21haWwuY29tIiwicmVtYWluaW5nX2R1ZSI6IjY3LjUwIiwibnVtX3Bl\nb3BsZSI6MiwidG8iOiIyMDE3MDQwMSIsImZyb20iOiIyMDE3MDMzMSIsImRlcG9zaXQiOiI3LjUw\nIn0=\n"\0
  CUR = 775
  LEN = 776

然后我用以下方法对其进行解码:

my $vars = JSON::XS->new->latin1->decode(decode_base64($base64));

但是,如果我这样做的话,在解码时:

Dump($vars->{comments});

我在 Dump() 中得到了这个;

SV = PV(0x31c06b8) at 0x2f4f208
  REFCNT = 1
  FLAGS = (POK,pPOK,UTF8)
  PV = 0x32635f0 "\303\255\303\263\303\251 test accents xxxxx"\0 [UTF8 "\x{ed}\x{f3}\x{e9} test accents xxxxx"]
  CUR = 25
  LEN = 32

如您所见,它仍然具有 UTF8 标志。我很困惑为什么它会这样做。

有人对我可以尝试的事情有一些想法吗?

更新:按照建议,我在编码之前和解码之后进行了转储(立即跳过数据库)。正如所建议的,它看起来正在将其转换为 utf8 :/

BEFORE ENCODING:

SV = PVMG(0x2a19a40) at 0x2a66588
  REFCNT = 1
  FLAGS = (POK,pPOK)
  IV = 0
  NV = 0
  PV = 0x2320af0 "\355\363\351 test accents xxxxx"\0
  CUR = 22
  LEN = 24

AFTER DECODING STRAIGHT AFTER:
SV = PV(0x2a64b08) at 0x2a6b730
  REFCNT = 1
  FLAGS = (POK,pPOK,UTF8)
  PV = 0x2ab2200 "\303\255\303\263\303\251 test accents xxxxx"\0 [UTF8 "\x{ed}\x{f3}\x{e9} test accents xxxxx"]
  CUR = 25
  LEN = 32

有什么想法可以阻止它这样做吗?

更新2:

传入的数据来自 jQuery $.ajax() 请求,因此采用 utf8 格式。所以我正在做的是将其转换为 iso-8859-1 格式:

$in->{$_} = Unicode::MapUTF8::from_utf8({-string => $in->{$_}, -charset => 'ISO-8859-1'});

不幸的是,所有网站和数据库都是 iso-8859-1 格式,因此我无法对任何数据使用 UTF8(这就是我进行转换的原因)

最佳答案

JSON::XS 正在对数据进行一些编码,因为它希望内容采用 utf8 格式。如果您不需要 JSON,但只想保留数据以便稍后检索,则可以使用不同的序列化方式,而不会干扰您的编码。

Storable模块随核心 Perl 一起提供,可让您将 Perl 数据结构转换为可以保存在数据库中的二进制表示形式。 BLOB 字段是有意义的。

use Storable;

my $binary = freeze($data_structure);

# somewhere else...

my $data_structure = thaw($binary)

关于perl - 将字符串转换为 is0-8859-1,以 base64 格式保存到数据库,但解码后结果为 utf8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42482088/

相关文章:

java - 从 UTF-8 文件读取时字符数字不正确

perl 按位与和按位移位

python - 使用文件夹名称作为文本文件中的一列

perl打印表输出

encoding - UTF-16与UTF-8兼容吗?

php - UTF-8贯穿始终

python - 包含 Unicode 字符的单词不会出现在 HTML 输出中

csv - 文件使用多重编码

Perl - 命令行输入和标准输入

regex - Perl 中的相等字符串不相等