2011-07-04 2 views
2

espérant que quelqu'un peut me diriger dans la direction de l'endroit où je vais mal avec ceci:Conversion UCS2 (Unknown LE ou BE) au format numérique Hex UTF-8 En utilisant Perl

J'ai une chaîne de (ce que Je crois) est UCS2 hexadécimal, mais le fournisseur ne peut pas me dire si c'est UCS2-LE ou UCS2-BE.

comme ceci: 0627062E062A062806270631

Il se traduit par ceci: اختبا

En arabe apparemment ... mais personne ne importe si j'essayez de le convertir sur six pans, en utilisant comme UCS2 droite (LE ou BE) ou pratiquement tout ce que je peux penser sous le soleil, je ne peux pas le transformer en natif-perl UTF-8 afin que je puisse ensuite ré-encoder comme UTF-8 standard (format natif de notre système).

code:

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

Il émet des caractères incompréhensibles pour le moment. Maintenant, une idée que je suis venu avec était de diviser la chaîne en question en sections de 4 caractères (c'est-à-dire par code hexadécimal), mais même en essayant cela avec une valeur hexadécimale UCS2 connue ne semble pas fonctionner.

Également essayé de forcer le codage de sortie, pas de joie là non plus.

Merci!

+0

Avez-vous essayé [Unicode :: String] (http://search.cpan.org/~gaas/Unicode-String-2.09/String.pm)? – fnokke

+1

@fnokke: NON! Unicode :: String est un module obsolète conçu pour fournir un support Unicode aux anciennes versions de Perl qui ne l'ont pas intégré. Personne ne devrait écrire du nouveau code qui l'utilise. – cjm

+0

@cjm: Bon à savoir! Merci – fnokke

Répondre

8

hex n'est pas le moyen de décoder une chaîne hexadécimale en une séquence d'octets. pack est. (hex produit un seul entier, pas une chaîne d'octets.) A part ça, vous étiez proche. Essayez ceci:

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

Remarque: Vous souhaitez probablement utiliser UTF-16BE au lieu de UCS-2BE. Ils sont fondamentalement la même chose, mais UTF-16BE autorise les paires de substitution, et pas UCS-2BE. Donc tout le texte UCS-2BE est également valide UTF-16BE, mais pas vice versa.

+0

cjm, malheureusement, j'écris ceci pour un API externe qui spécifie l'entrée comme UCS-2 ou je ne serais pas près d'elle, mais merci beaucoup pour votre aide! Il m'a sauvé un cauchemar de tester divers morceaux, car cela semble bien fonctionner. – Chris

+1

@Chris, je crois que vous voulez dire qu'il est * sortie * UCS-2. (Si vous attendez une entrée 'UCS-2', alors pourquoi produisez-vous' UTF-8'.) Si c'est le cas, vous pouvez utiliser UTF-16 parce que UTF-16 est un sur-ensemble de 'UCS-2' . Je recommande également d'utiliser 'UTF-16' car votre application continuera à fonctionner si l'API commence à émettre UTF-16. (Si quelque chose attend l'entrée "UCS-2' *, alors oui, on devrait utiliser' UCS-2'.) – ikegami

+0

ikegami, c'était malheureusement une entrée UCS-2 explicite, pas ma préférence! – Chris