div.main {margin-left: 20pt; margin-right: 20pt}
Использование библиотеки MIME-Base64
Suhhinin A., Webscript.ru
Библиотека MIME-Base64 включает в себя 2 модуля:
MIME::Base64;
MIME::QoutedPrint;
Первый - MIME::Base64служит для кодирвания/раскодирования строк в
Base64 кодированные строки согласно спецификации RFC 2045 - MIME
(Multipurpose Internet Mail Extensions). Этот метод заключается в том, что
все символы кодируются в форму, совершенно нечитабельную человеком. Для
кодирования используется подмножество из 65 символов US-ASCII
([A-Za-z0-9+/=]). например, строка вида =?koi8-r?B?+sTSwdfT1NfVytTFIQ==?=
по-русски будет звучать как Здравствуйте! Заметить надо, что закодированная строка начинается после
комбинации ?B? и заканчивается ?=. В модуле
две функции:
decode_base64($str);
encode_base64($str, [$eol]); Этой функцией выполняется
кодирование данных. Первый аргумент - кодируемая строка, второй - признак
окончания строки (по умолчанию - "n").Возвращаемая кодированная строка
разбивается на строки не более, чем 76 символов, и заканчивающиеся
символом $eol. Если не хотите, чтобы результат был разбит на строки, в
качестве второго аргумента передайте пустую строку. Если не хотите
импортировать процедуры в пространство имен, можно использовать следующим
образом: use MIME::Base64 ();
$test = "Привет!";
$encoded = MIME::Base64::encode($test);
$decoded = MIME::Base64::decode($encoded);
print $test,"n";
print $encoded, "n";
print $decoded, "n";
результат будет следующий: Привет!
j+CooqXiIQ==
Привет!
после кодированной строки идет пустая строка, ибо результат
encode возвращается с символом "n"; Функция
decode_base64($str) раскодирует ранее закодированную строку.
предназначен
для кодирования/раскодирования Quoted-printable строк (Американцы любят
придумывать труднопереводимые термины, по русски звучит как
"ограниченные разделителями печатаемые строки" Выглядит сия
строка так: =FA=C4=D2=C1=D7=D3=D4=D7=D5=CA=D4=C5!
по-русски будет звучать как Здравствуйте! Заметим, что, в отличие от Base64 восклицательный знак не
закодирован. Сей метод кодирования представляет закодированную информацию
в объеме, примерно в три раза больше, нежели исходный текст. Непечатыемые
символы (Янкесы все, что не входит в их алфавит, обозвали непечатыемыми)
представляются знаком "=" и за ним две шесстнадцатиричные цифры. В модуле
две функции:
encode_qp($str); Эта функция возвращает закодированную строку. Функция
не заменяет сивол "n" на комбинацию CRLF.
decode_qp($str);Эта функция фозвращает раскодированную строку в виде
чистого текста. Прямой вызов функции производится так: use MIME::QuotedPrint ();
$encoded = MIME::QuotedPrint::encode($decoded);
$decoded = MIME::QuotedPrint::decode($encoded);
Поскольку сии методы широко применяются в почтовых программах, и
широко применяются оба метода, нужно знать, как заставить вашу
Perl-программу различать эти строки. Очень часто кодируются поля "from",
"to","Subject" и тело письма, особенно, если посылается письмо из
OutlookExpress. Служебные поля в заголовке помечаются следующим
образом: from, to, subj: =?koi8-r?B?+sTSwdfT1NfVytTFIQ==?=
между =? и следующим ? идет тип кодовой
таблицы строки-источника.
B? означает Base-64 encoding, ?Q означает
Quoted Printable encoding. Значит, для определения типа строки
можно нарисовать следующий код: # такие сложности с определением подстроки вызваны тем,
# что выражение $str =~ "B?" не дает нужного результата
# под ActivePerl в Windows.
my $ind1 = index $str,"B?"; # ищем признак encoded-base64
my $ind2 = index $str,"Q?"; # ищем признак encoded quoted-printable
if ($ind1 > 0) { # если строка encoded-base64
($b,$s) = split(/B?/,$str); #отрубаем служебную информацию вида =?koi8-r?B?
($st,$rest) = split(/?=/,$s); #отрубаем окончание строки ?=
$result = decode_base64($st); # получаем результат
}
if ($ind2 > 0) { # если строка encoded quoted-printable
($b,$s) = split(/Q?/,$str); # отрубаем служебную информацию вида =?koi8-r?Q?
($st,$rest) = split(/?=/,$s); # отрубаем окончание строки ?=
$result = decode_qp($st); # получаем результат
}
Собственно, с закодированными полями в заголовке письма разобрались.
Теперь на очереди тело письма. Чтобы определить вид кодировки в теле
письма, нам нужно сновапорыться в header-е сообщения. В заголовках
кодированных писем должна присутствовать строка типа: Content-Type: text/plain; charset="koi8-r"
Content-Transfer-Encoding: quoted-printable
В этих полях, определяется, в какой кодировке исходное сообщение
(koi8-r,windows-1251,....), и тип MIME кодировки (quoted-printable,
base-64, 8bit,....). Если MIME кодировка 8bit, то делать ничего не надо,
если иная, то читаем сообщение построчно и раскодируем его: # пример для quoted-printable;
foreach $line(@message_body) {
print decode_qp($line);
}
Строки, содержащие HTML код и строки, набранные латинскими знаками
(US/English) перекодироваться не будут. Вот, собственно, и все. В
наборе библиотек MIME есть еще пакеты
Lite-1, Lite-2 "облегченные" MIME кодеры/декодеры, с помощью них
можно создавать / читать многосекционные MIME-encoded сообщения
(например, вложенная картинка),
HTML для преобразования HTML письма в MIME-Lite формат,
Tools для разбора и создания MIME вхождений,
ispMailGate для создания фильтров на почтовом сервере с демоном
sendmail. Чтобы их разбирать и описывать, нужен десяток статей
такого же объема, как эта, а посему, позвольте на этом закончить.
|