Я имею строку 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] = ''});
Чтобы выяснить, в какой кодировке используется что-то неизвестное, вам просто нужно попробовать поискать. Модули Encode::Detect и Encode::Guess автоматизируют это. (Если у вас возникли проблемы с компиляцией Encode::Detect, попробуйте вместо него вилку 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);
Я нахожу, что кодировка '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. Это тоже кодировка с потерями, но не такая ужасная, как обычная кодировка
выше.
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.
Модуль Encode имеет возможность попробовать это сделать. Вы декодируете
необработанные октеты тем, что считаете кодировкой. Если октеты не представляют собой правильную кодировку, они взорвутся, и вы поймаете их с помощью eval. В противном случае, вы получите обратно правильно закодированную строку. Например:
use Encode;
my $a_with_ring =
eval { decode( 'UTF-8', "\x6b\xc5", Encode::FB_CROAK ) }
or die "Could not decode string: $@";
Недостаток в том, что одна и та же последовательность октетов может быть действительна в нескольких кодировках
Больше я хочу сказать об этом в ближайшем выпуске Effective Perl Programming, 2-е издание, в котором есть целая глава, посвященная работе с Юникодом. Я думаю, что мой издатель разозлится, если я все это опубликую. :)
Вы также можете посмотреть Juerd's Unicode Advice, а также некоторые документы по Юникоду, которые поставляются вместе с Perl.
.Вы также можете использовать следующий код для шифрования и дешифрования кода
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);