使用Perl将数字十六进制格式的UCS2(未知LE或BE)转换为UTF-8

Chr*_*ris 3 perl hex ucs2 utf-8 character-encoding

希望有人可以指出我在这方面出错的方向:

我有一串(我相信)是十六进制编码的UCS2,但提供商不能告诉我它是UCS2-LE还是UCS2-BE.

像这样:0627062E062A062806270631

它转化为:اختبا

在阿拉伯语中显然......但无论我是否尝试将其转换为十六进制,使用它作为直UCS2(LE或BE)或几乎任何我能想到的在太阳下的其他东西,我都不能把它变成原生的 - perl UTF-8然后我可以重新编码为标准UTF-8(我们系统的本机格式).

码:

my $string = "0627062E062A062806270631";
my $decodedHex = hex($string);

#NEAREST
my $perlDecodedUTF8 = decode("UCS-2BE", $decodedHex);
my $utf8 = encode('UTF-8',$perlDecodedUTF8);

open(ARABICTEST,">ucs2test.txt");
print(ARABICTEST $perlDecodedUTF8);
print("Done!");
close(ARABICTEST);
Run Code Online (Sandbox Code Playgroud)

它目前输出乱码.

现在我想到的一个想法是将有问题的字符串拆分成4个字符的部分(即每个十六进制代码),但即使尝试使用单独的,已知的UC​​S2十六进制值也不会起作用.

还尝试强制输出编码,也没有欢乐.

谢谢!

cjm*_*cjm 9

hex不是将十六进制字符串解码为字节序列的方法. pack是.(hex产生一个整数,而不是一串字节.)除此之外,你很接近.试试这个:

use strict;
use warnings;
use Encode;

my $string = "0627062E062A062806270631";
my $decodedHex = pack('H*', $string);

my $perlDecodedUTF8 = decode("UCS-2BE", $decodedHex);

open(my $ARABICTEST,">:utf8", "ucs2test.txt");
print $ARABICTEST $perlDecodedUTF8;
print("Done!");
close($ARABICTEST);
Run Code Online (Sandbox Code Playgroud)

注意:您可能希望使用UTF-16BE而不是UCS-2BE.它们基本上是相同的,但UTF-16BE允许代理对,而UCS-2BE则不允许.因此,所有UCS-2BE文本也是有效的UTF-16BE,但反之亦然.