将字节序列转换为适当的字符

时间:2017-12-14 11:06:18

标签: perl utf-8

我使用这个site来转换字节序列,如下所示:

d d°d±Ñ<ни

进入正确的字符序列:

Рабыни

该网站似乎将UTF8序列解码为其原始字符。出于某种原因,我的一些文件名已损坏,我需要将它们转换回原始文件。

由于文件数量不少,我决定为此目的编写一个perl脚本。我试过这个

#!/usr/bin/perl
use utf8;
$str = "Рабыни.avi";
utf8::decode($str);
binmode STDOUT, ":utf8";
print "$str\n";

作为对一个文件名的测试。运行脚本时,我将输出重定向到文件。当我看到文件的内容时,我看到内容与输入字符串相同,并且没有进行转换。这是输出与网站为这样的序列转换的内容一致:

d°Ð½Ð³Ðμлов

我尝试使用ActivePerl在Linux(Ubuntu)和Windows上运行脚本,两者都给出相同的结果。专注于Windows,您认为脚本的错误是什么?

由于

1 个答案:

答案 0 :(得分:5)

使用UTF-8对Рабыни进行编码会产生D0.A0.D0.B0.D0.B1.D1.8B.D0.BD.D0.B8

但是,РабыниD0.20.D0.B0.D0.B1.D1.2039.D0.BD.D0.B8

主要问题是utf8::decode($str);失败,因为Рабыни不是有效的UTF-8。 Рабыни的编码已被不可逆转地破坏。

至于Windows,

#!/usr/bin/perl

my $terminal_enc_layer;
BEGIN {
    $terminal_enc_layer = $^O eq 'MSWin32'
        ? do { require Win32; ":encoding(cp".Win32::GetACP().")" }
        : ":locale";
}

use utf8;
use open ':std', $terminal_enc_layer;

use strict;
use warnings;

my $str = "\xD0\xA0\xD0\xB0\xD0\xB1\xD1\x8B\xD0\xBD\xD0\xB8";

utf8::decode($str)
   or die "Bad data";

print "$str\n";