Подтвердить что ты не робот

Как можно угадать кодировку строки в Perl?

У меня есть строка Unicode и не знаю, какова ее кодировка. Когда эта строка считывается программой Perl, есть ли кодировка по умолчанию, которую Perl будет использовать? Если да, то как я могу узнать, что это такое?

Я пытаюсь избавиться от символов, отличных от ASCII, от ввода. Я нашел это на каком-то форуме, который это сделает.

my $line = encode('ascii', normalize('KD', $myutf), sub {$_[0] = ''});

Как это будет работать, если не указано кодирование ввода? Должен ли он быть указан так?

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

Ответ 1

Чтобы узнать, в какой кодировке используется что-то неизвестное, вам просто нужно попробовать и посмотреть. Модули Encode:: Detect и Encode::Guess автоматизируют это, (Если у вас возникли проблемы с компиляцией Encode:: Detect, попробуйте использовать его fork Encode::Detective.)

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

Я нахожу, что encode 'ascii' является хромым решением для избавления от символов, отличных от ASCII. Все будет заменено вопросительными знаками; это слишком мало, чтобы быть полезным.

# 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.

Если вы хотите читать ASCII-текст, я рекомендую вместо этого Text:: Unidecode. Это тоже кодировка с потерями, но не такая страшная, как обычная encode выше.

use utf8;
use Text::Unidecode;
my $string = 'This year I went to 北京 Perl workshop.';
print unidecode($string); # This year I went to Bei Jing  Perl workshop.

Однако, избегайте этих кодировок с потерями, если вы можете им помочь. Если вы захотите изменить операцию позже, выберите либо один из PERLQQ или 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.

Ответ 2

Модуль Encode позволяет вам это сделать. Вы decode необработанные октеты с тем, что, по вашему мнению, является кодировкой. Если октеты не представляют действительную кодировку, она взрывается, и вы поймаете ее с помощью eval. В противном случае вы вернете правильно закодированную строку. Например:

 use Encode;

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

Это имеет тот недостаток, что одна и та же последовательность октетов может быть действительной при нескольких кодировках

У меня есть еще об этом в следующем Эффективном программировании на Perl, 2nd Edition, в котором есть целая глава по работе с Unicode. Я думаю, что мой издатель разозлится, если я разместил все это.:)

Вы также можете увидеть Juerd Unicode Advice, а также некоторые из документов Unicode, которые поставляются с Perl.

Ответ 3

Вы также можете использовать следующий код для шифрования и дешифрования кода

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