2011-07-04 16 views
2

希望有人能指出我在我與這個走錯了方向:我有一個字符串轉換UCS2(未知LE或BE)在數字十六進制格式爲UTF-8使用Perl

(什麼我相信)是十六進制編碼的UCS2,但提供商不能告訴我它是UCS2-LE還是UCS2-BE。

像這樣:0627062E062A062806270631

它翻譯成這樣:اختبا

在阿拉伯語中顯然......但是,沒有也罷,我嘗試轉換出來十六進制的,用它作爲直UCS2(LE或BE )或者其他我可以想到的任何其他東西,我不能將它變成native-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); 

它的那一刻輸出亂碼字符。

現在我想到的一個想法是將問題的字符串拆分爲4個字符的部分(即每個十六進制代碼),但即使使用單個已知的UC​​S2十六進制值嘗試此操作似乎也不起作用。

也嘗試強制輸出編碼,也沒有喜悅。

謝謝!

+0

你試過[Unicode :: String](http://search.cpan.org/~gaas/Unicode-String-2.09/String.pm)嗎? – fnokke

+1

@fnokke:不! Unicode :: String是一個過時的模塊,旨在爲古代版本的Perl提供Unicode支持,而這些版本沒有內置。沒有人應該編寫使用它的新代碼。 – cjm

+0

@cjm:很高興知道!謝謝 – fnokke

回答

8

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); 

注意:您可能想要使用UTF-16BE而不是UCS-2BE。它們基本上是一樣的,但UTF-16BE允許代理對,而UCS-2BE則不允許。所以所有的UCS-2BE文本都是有效的UTF-16BE,但反過來也是一樣。

+0

cjm,可悲的是我寫這個爲外部API將輸入指定爲UCS-2,否則我不會靠近它,但很多非常感謝您的幫助!因爲這看起來工作正常,所以給我一個測試各種零碎件的惡夢。 – Chris

+1

@Chris,我相信你的意思是*輸出* UCS-2。 (如果期望'UCS-2'輸入,那麼爲什麼你要生成'UTF-8')。如果是這樣,使用'UTF-16'是安全的,因爲'UTF-16'是'UCS-2' 。我也推薦使用'UTF-16',因爲如果API開始發佈UTF-16,你的應用程序將繼續工作。 (如果有什麼需要'UCS-2' *輸入*,那麼是的,應該使用'UCS-2'。) – ikegami

+0

ikegami,很遺憾顯式的UCS-2輸入,不是我的偏好! – Chris

相關問題