2009-12-28 19 views
22

Ich habe eine Unicode-Zeichenfolge und weiß nicht, was die Codierung ist. Wenn diese Zeichenfolge von einem Perl-Programm gelesen wird, gibt es eine Standardcodierung, die von Perl verwendet wird? Wenn ja, wie kann ich herausfinden, was es ist?Wie kann ich die Codierung einer Zeichenfolge in Perl erraten?

Ich versuche, Nicht-ASCII-Zeichen von der Eingabe loszuwerden. Ich fand dies in einem Forum, das es tun wird

Wie funktioniert das oben, wenn keine Eingabe codiert ist? Sollte es so angegeben werden?

my $line = encode('ascii', normalize('KD', decode($myutf, 'input-encoding'), sub {$_[0] = ''}); 
+1

mich korrigieren zu entschlüsseln, wenn ich falsch liege, aber ich dachte, der ganze Sinn von Unicode ist, dass es nicht existiert eine "Kodierung" - alles ist da. –

+3

Sie haben keine Unicode-Zeichenfolge. Sie haben eine Datei voller Bytes, die eine Unicode-Zeichenfolge in einer Codierung darstellen. Wenn Sie die Kodierung der Datei nicht kennen, prüfen Sie am Anfang der Datei nach einem Byte-Order-Marker. Wenn es keine Stückliste gibt, hast du kein Glück. –

+0

Es sieht so aus, als ob Sie mindestens zwei separate Fragen stellen (1. und 2. Absatz). – Amnon

Antwort

29

Um herauszufinden, in welcher Codierung etwas unbekannt verwendet, müssen Sie nur versuchen und schauen. Die Module Encode::Detect und Encode::Guess automatisieren das. (Wenn Sie Probleme haben Kompilieren Encode :: erkennen, versuchen, seine Gabel Encode::Detective statt.)

use Encode::Detect::Detector; 
my $unknown = "\x{54}\x{68}\x{69}\x{73}\x{20}\x{79}\x{65}\x{61}\x{72}\x{20}". 
       "\x{49}\x{20}\x{77}\x{65}\x{6e}\x{74}\x{20}\x{74}\x{6f}\x{20}". 
       "\x{b1}\x{b1}\x{be}\x{a9}\x{20}\x{50}\x{65}\x{72}\x{6c}\x{20}". 
       "\x{77}\x{6f}\x{72}\x{6b}\x{73}\x{68}\x{6f}\x{70}\x{2e}"; 
my $encoding_name = Encode::Detect::Detector::detect($unknown); 
print $encoding_name; # gb18030 

use Encode; 
my $string = decode($encoding_name, $unknown); 

Ich finde encode 'ascii' ist eine lahme Lösung für nicht-ASCII-Zeichen loszuwerden. Alles wird durch Fragezeichen ersetzt; Das ist zu verlustreich, um nützlich zu sein.

# Bad example; don't do this. 
use utf8; 
use Encode; 
my $string = 'This year I went to 北京 Perl workshop.'; 
print encode('ascii', $string); # This year I went to ?? Perl workshop. 

Wenn Sie lesbaren ASCII-Text wollen, empfehle ich Text::Unidecode statt. Auch dies ist eine verlustbehaftete Kodierung, aber nicht so schlimm wie einfach encode oben.

Vermeiden Sie jedoch diese verlustreichen Codierungen, wenn Sie es helfen können. Falls Sie den Vorgang später rückgängig machen möchten, wählen Sie entweder PERLQQ oder XMLCREF.

use utf8; 
use Encode qw(encode PERLQQ XMLCREF); 
my $string = 'This year I went to 北京 Perl workshop.'; 
print encode('ascii', $string, PERLQQ); # This year I went to \x{5317}\x{4eac} Perl workshop. 
print encode('ascii', $string, XMLCREF); # This year I went to 北京 Perl workshop. 
+0

Der Eingang, den ich erhalte, verwendet immer den lateinischen Zeichensatz. Die von mir verwendete Normalisierungsfunktion würde dann "Café" in "Cafe" umwandeln. Dies funktioniert jedoch nicht in allen Fällen. Würden Sie angesichts dessen die Methode PERLQQ oder XMLCREF bevorzugen? – Maulin

+0

Es ist egal, was ich bevorzuge - es ist dein Code und deine Verantwortung, und nur du kennst alle Umstände. Wenn Sie mit Café → Cafe wirklich zufrieden sind, ersetzen Sie Ihre benutzerdefinierte Funktion durch "Text :: Unidecode". Das funktioniert in allen Fällen. – daxim

+0

Danke. Ich denke, ich werde es versuchen. – Maulin

3

Das Encode Modul hat eine Art und Weise, die Sie versuchen können, dies zu tun. Sie decode die rohen Oktette mit, was Sie denken, die Codierung ist. Wenn die Oktetts keine gültige Kodierung darstellen, explodiert sie und Sie fangen sie mit einem Eval ein. Andernfalls erhalten Sie eine ordnungsgemäß codierte Zeichenfolge zurück. Zum Beispiel:

use Encode; 

my $a_with_ring = 
    eval { decode('UTF-8', "\x6b\xc5", Encode::FB_CROAK) } 
    or die "Could not decode string: [email protected]"; 

Dies hat den Nachteil, dass die gleiche Oktett Sequenz in mehrere Kodierungen gültig sein kann

Ich habe mehr zu sagen über diese in den kommenden Effective Perl Programming, 2nd Edition, die sich auf den Umgang mit Unicode ein ganzes Kapitel hat . Ich denke, mein Verleger würde verrückt werden, wenn ich die ganze Sache veröffentlichen würde. :) Sie können auch Juerd's Unicode Advice sehen, sowie einige der Unicode-Dokumente, die mit Perl geliefert werden.

-4

können Sie den folgenden Code verwenden auch, zu verschlüsseln und den Code

sub ENCRYPT_DECRYPT() { 
    my $Str_Message=$_[0]; 
    my $Len_Str_Message=length($Str_Message); 

    my $Str_Encrypted_Message=""; 
    for (my $Position = 0;$Position<$Len_Str_Message;$Position++){ 
     my $Key_To_Use = (($Len_Str_Message+$Position)+1); 
      $Key_To_Use =(255+$Key_To_Use) % 255; 
     my $Byte_To_Be_Encrypted = substr($Str_Message, $Position, 1); 
     my $Ascii_Num_Byte_To_Encrypt = ord($Byte_To_Be_Encrypted); 
     my $Xored_Byte = $Ascii_Num_Byte_To_Encrypt^$Key_To_Use; 
      my $Encrypted_Byte = chr($Xored_Byte); 
     $Str_Encrypted_Message .= $Encrypted_Byte; 

    } 
    return $Str_Encrypted_Message; 
} 

my $var=&ENCRYPT_DECRYPT("hai"); 
print &ENCRYPT_DECRYPT($var); 
+0

Die Frage bezog sich auf Textkodierungen und nicht auf Verschlüsselung. – Flimm

Verwandte Themen