Рассылка закрыта
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
← Декабрь 2000 → | ||||||
1
|
2
|
3
|
||||
---|---|---|---|---|---|---|
4
|
5
|
6
|
7
|
8
|
9
|
10
|
11
|
12
|
13
|
14
|
15
|
16
|
|
18
|
19
|
20
|
21
|
22
|
23
|
24
|
26
|
27
|
28
|
29
|
30
|
Статистика
за неделю
Программирование скриптов на Perl'e (Выпуск №10)
Программирование скриптов на Perl'e (выпуск 10).
Здравствуйте дорогие мои подписчики.
Сегодня в выпуске:
- Несколько слов перед началом
- Perl для начинающих - Преобразование кодировок
- CGI-программирование - Счетчик посещений : Модификация
- CGI-программирование - Гостевая книга : Безопасность
- "Лучшая ссылка"
- О рассылке
Несколько слов перед началом
Вот, наконец, и третье тысячелетие на пороге. И в этот раз оно надеюсь, наступит, в отличие от прошлого года.
Я поздравляю всех Вас, дорогие мои подписчики, с наступающим Новым годом. Хочу пожелать Вам в 2001 году добиться огромных успехов в жизни.
Сразу хочу предупредить, что с выходом следующего номера рассылки возможна задержка. Ну, сами понимаете. :-)
"Еще одно знаменательное событие", обещанное в прошлом выпуске, свершиться не успело, но работа над ним идет полным ходом и в январе 2001 года обязательно завершится.
Сегодня у нас в разделе, посвященном CGI-программированию две коротенькие темы. Но обо всем по порядку. Сегодняшние темы:
Perl для начинающих - Преобразование кодировок
Сегодня мы начнем практически применять накопленные знания, и начнем со скрипта преобразования кодировки. На его примере мы рассмотрим работу с командной строкой, проверки условий, циклы, работу со строками и файлами и, кроме того, работу с подпрограммами.
Итак, приступим.
Прежде всего, надо определиться с тем как будет работать программа. На мой взгляд, лучше всего не изменять исходный файл, а сохранять перекодированный текст в другом файле.
Самой первой строкой в Perl-программе должен быть путь к интерпретатору Perl'а. Для Unix-систем это будет:
#!/usr/bin/perl или #!/usr/local/bin/perlдругие пути встречаются намного реже. Для Windows/DOS-систем этот путь может быть что-то типа:
#!c:/compile/perl/bin/perl.exeили любой другой, смотря где на Вашем компьютере установлен интерпретатор Perl'а.
Условимся, что запуск программы будем выполнять с тремя параметрами:
- исходный файл, подлежащий перекодировке;
- целевой файл, куда будет записан перекодированный текст;
- режим работы - из какой кодировки в какую будет производиться перекодирование.
При запуске проверим количество параметров в командной строке и если их меньше трех, то сообщим об этом и выйдем из программы. Количество параметров большее, чем три нам неважно, т. к. в программе используются только первые три.
Делается это при помощи следующего фрагмента кода:
if (@ARGV<3) { print "trnfile - file codetable translator.\n"; print "(c)IVA 2000\n\n"; print "Usage: trnfile file_in file_out mode\n"; print " mode - from_table2to_table\n\n"; print "Used tables: dos, win, koi\n\n"; print "Example: trnfile index.html index_win.html koi2win\n"; exit; }Здесь @ARGV - массив, содержащий параметры строки запуска программы. Проверка if (@ARGV<3) возвращает "истину" если число аргументов меньше трех и "ложь" в противном случае. Если результат проверки - "ложь", т. е. количество аргументов, переданных программе, удовлетворяет требованиям, то переходим к выполнению программы.
Теперь мы определяем три строки, содержащие DOS, Win и KOI кодировки русского алфавита (все 66 символов) - это переменные с именами $dos, $win и $koi, соответственно. В принципе можно было бы представить кодировки не строками, а массивами, но в этом случае определения таблиц становится более громоздким. Кроме того, мы ничего не выиграем при поиске символа не в переменной-строке, а в переменной-массиве.
$dos=" ЎўЈ¤Ґс¦§Ё©Є«¬-®ЇабвгдежзийклмнопЂЃ‚ѓ„…р†‡€‰Љ‹ЊЌЋЏђ‘’“”∙–—™љ›њќћџ"; $win="абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"; $koi="БВЧЗДЕЈЦЪЙКЛМНОПРТУФХЖИГЮЫЭЯЩШЬАСбвчздеіцъйклмнопртуфхжигюыэящшьас";Заранее хочу предостеречь Вас от возможной ошибки. Дело в том, что я верстаю рассылку в кодировке Win-1251, а на Subscribe ее автоматически перекодируют в формат KOI-8, в связи с чем могут произойти (а точнее именно произойдут) некоторые изменения в таблицах кодировок. Для того чтобы восстановить их, Вам можно воспользоваться любым текстовым редактором с поддержкой этих кодировок. В качестве такового могу предложить обычный F4-редактор из состава DOS Navigator'а.
Теперь нам нужно проверить корректность задания режима работы. Программа допускает указание 6 режимов работы:
- win2dos - из Win-кодировки в DOS-кодировку;
- win2koi - из Win-кодировки в Koi-кодировку;
- dos2win - из DOS-кодировки в Win-кодировку;
- dos2koi - из Win-кодировки в Koi-кодировку;
- koi2win - из Koi-кодировки в Win-кодировку;
- koi2dos - из Koi-кодировки в DOS-кодировку.
if (index($mode, "dos")==0) { $in_tab=$dos } elsif (index($mode, "dos")==4) { $out_tab=$dos; } else { $notuse++; }После того, как все три вхождения проверены, мы проверяем значение переменной $notuse. Если ее значение больше 1, это значит, что режим трансляции был задан неверно. Мы выводим сообщение об этом и завершаем программу:
die "Error specified \"mode\" param." if ($notuse>1);Продолжим. Теперь мы открываем оба файла. Первый для - чтения (по умолчанию), а второй - для записи (явно):
open F1, "$ARGV[0]" || die "Cannot open $ARGV[0] $!\n"; open F2, ">$ARGV[1]" || die "Cannot open $ARGV[1] $!\n";В Perl'е начальный индекс массива, как и в С, равен нулю. В этих выражениях, как Вы видите, используется оператор "логическое или" - "||" у которого правая часть не выполняется, если левая вернет значение "истина", т. е. если файл откроется. Если же файл не откроется, то выполнится правая часть, в которой находится оператор die, он выведет строку "Cannot open имя_файла код_ошибки" и завершит выполнение программы.
Теперь, после того, как оба файла открыты и начинается самое интересное.
Мы читаем по одной строке из первого файла, преобразуем кодировку и записываем строку во второй файл:
while (<F1>) { $newline=&trans($_); print F2 $newline; } По достижении конца первого файла цикл прекращается, и мы закрываем оба файла: close(F1); close(F2);Теперь непосредственно о преобразовании кодировки.
Для преобразования мы берем прочитанную строку и вводим цикл, с количеством итераций равным длине строки:
for ($i=0; $i<length($instr); $i++)Далее в этом цикле с помощью функции substr(строка, начало, длина) получаем поочередно каждый символ строки:
$symb=substr($instr, $i, 1);После того, как символ получен, мы определяем позицию его вхождения в строку исходной кодировки:
$pos=index($in_tab, $symb);Если такой символ в строке имеется (т. е. если это любая строчная или заглавная буква русского алфавита), то мы из строки целевой кодировки по полученной позиции считываем символ и добавляем его в конец создаваемой строки. Если же такой символ в строке отсутствует, то добавляем его в конец создаваемой строки без изменений:
if ($pos>=0) { $newsymb=substr($out_tab, $pos, 1); $outstr.=$newsymb; } else { $outstr.=$symb; }Вроде бы все. Осталось сказать только, что сама процедура перекодировки реализована в виде подпрограммы с именем "trans".
А теперь полный текст программы trnfile.pl:
#!/usr/bin/perl if (@ARGV<3) { print "trnfile - file codetable translator.\n"; print "(c)IVA 2000\n\n"; print "Usage: trnfile file_in file_out mode\n"; print " mode - from_table2to_table\n\n"; print "Used tables: dos, win, koi\n\n"; print "Example: trnfile index.html index_win.html koi2win\n"; exit; } $dos=" ЎўЈ¤Ґс¦§Ё©Є«¬-®ЇабвгдежзийклмнопЂЃ‚ѓ„…р†‡€‰Љ‹ЊЌЋЏђ‘’“”∙–—™љ›њќћџ"; $win="абвгдеёжзийклмнопрстуфхцчшщъыьэюяАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"; $koi="БВЧЗДЕЈЦЪЙКЛМНОПРТУФХЖИГЮЫЭЯЩШЬАСбвчздеіцъйклмнопртуфхжигюыэящшьас"; $notuse=0; $in_tab=""; $out_tab=""; $mode=$ARGV[2]; if (index($mode, "dos")==0) { $in_tab=$dos } elsif (index($mode, "dos")==4) { $out_tab=$dos; } else { $notuse++; } if (index($mode, "win")==0) { $in_tab=$win } elsif (index($mode, "win")==4) { $out_tab=$win; } else { $notuse++; } if (index($mode, "koi")==0) { $in_tab=$koi } elsif (index($mode, "koi")==4) { $out_tab=$koi; } else { $notuse++; } die "Error specified \"mode\" param." if ($notuse>1); open F1, "$ARGV[0]" || die "Cannot open $ARGV[0] $!\n"; open F2, ">$ARGV[1]" || die "Cannot open $ARGV[1] $!\n"; while (<F1>) { $newline=&trans($_); print F2 $newline; } close(F1); close(F2); sub trans { $instr= $_[0]; $outstr=""; for ($i=0; $i<length($instr); $i++) { $symb=substr($instr, $i, 1); $pos=index($in_tab, $symb); if ($pos>=0) { $newsymb=substr($out_tab, $pos, 1); $outstr.=$newsymb; } else { $outstr.=$symb; } } return ($outstr); }На этом на сегодня все.
CGI-программирование - Счетчик посещений : Модификация
Как Вы помните, в восьмом выпуске рассылки был разобран скрипт счетчика посещений и сегодня я хочу еще раз к нему вернуться.
В процессе его эксплуатации мною, была выявлена одна странность: при вызове скрипта с параметром числа цифр меньше чем 7 скрипт формирует нормальный рисунок, в противном случае изображение формируется некорректно. В принципе казалось бы 6 цифр - это ведь почти миллион посещений, ну кто наберет столько? Но почему бы и нет. Почему бы не 5, 6, 10 миллионов, конечно со временем. И что тогда? И вот поэтому я предлагаю модификацию счетчика. Она весьма проста. Нужно просто фрагмент кода:
if (($digits_in_image)>scalar(@count)) { for ($i=0; $i<($digits_in_image-scalar(@count)); $i++) { unshift @count, 0; } } заменить на: if (($digits_in_image-1)>length($counter)) { for ($i=0; $i<($digits_in_image-1-length($counter)); $i++) { unshift @count, 0; } }Теоретически, в данном примере, выражения length($counter) и scalar(@count) должны возвращать одинаковые значения, т. к. в первом случае вычисляется длина переменной $counter (которая, как Вы помните, в Perl'е является строкой), равная количеству цифр, а во втором - количество элементов массива @count, равное, опять-таки количеству цифр, но этого почему-то не происходит.
После этой замены скрипт формирует корректно изображение с любым количеством цифр.
CGI-программирование - Гостевая книга : Безопасность
После выхода прошлого номера рассылки ко мне пришло письмо, которое я хочу частично процитировать. Надеюсь, автор не будет против.
Здравствуйте, Виталий!
Поздравляю Вас с наступающим праздником!
Желаю Вам и Вашей рассылке всего самого наилучшего в новом году (и новом веке)!
Пробовал Вашу Гостевую книгу из 9-го выпуска. Очень понравилась.
Дополнительная функция, которую, по моему мнению, надо бы в нее внести - защита от тэгов в сообщениях.
Гости-то ведь бывают разные :-)
В гостевых книгах некоторых сайтов (очевидно, имеющих такую защиту), я встречал "дружеские сообщения" типа
1. #include virtual="/usr/bin/cat /etc/passwd" (очевидно, guestbook "съел" угловые скобки :-)) ) 2. script window.location="http://мой_хороший_сайт/"; /scriptи подобные.
Можно сделать и др. "неподобающие вещи" - например, вставить код своего баннера и т.п.
...
С уважением,
Андрей
andrew@bars.agava.ru
http://angel07.webservis.ru/
Я совершенно согласен с Андреем и предлагаю дополнение к гостевой книге. Для этого нужно немного модифицировать код процедуры разбора входного запроса. Заменять будем следующий блок:
foreach $pair (@pairs) { ($name, $value)=split(/=/, $pair); $value=~tr/+/ /; $value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/gem; $FORM{$name}=$value; }Можно пойти по пути удаления всего, что заключено между символами угловых скобок, т. е. вырезать все HTML-комментарии, в которых могут быть заключены SSI-инструкции, и все HTML-тэги. Сделать это можно следующим образом:
foreach $pair (@pairs) { ($name, $value)=split(/=/, $pair); $value=~tr/+/ /; $value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/gem; $value=~s/<!--(.|\n)*-->//gem; # вырезка многострочных HTML-комментариев $value=~s/<([^>]|\n)*>//gem; # вырезка HTML-тэгов $FORM{$name}=$value; }А можно ничего не удалять. Просто взять и заменить все угловые скобки, на их коды. Выглядеть это будет просто замечательно. На экране вместо вставленного в сообщение баннера будет его HTML-код. Делается это так:
foreach $pair (@pairs) { ($name, $value)=split(/=/, $pair); $value=~tr/+/ /; $value=~s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/gem; $value=~s/</</gem; $value=~s/>/>/gem; $FORM{$name}=$value; }Удачных Вам гостей.
"Лучшая ссылка"
Сегодня в этом разделе речь пойдет о компьютерной библиотеке RTFM - VinNest Documentation Home (http://rtfm.vn.ua/).
Ссылка на этот ресурс мне попалась давно, но мой поход туда по ряду причин постоянно откладывался. И как оказалось совершенно зря. Причина проста. Дело в том, что на этом сайте находится, процитирую: "Почти полное собрание книг O'Reilly по программированию на Perl, Java, WWW программированию, TCP/IP и устройству UNIX систем. 28 книг в онлайн." И ведь действительно все это там есть.
По программированию на Perl'е там находятся следующие книги:
- Perl in a Nutchell
- Learning Perl
- Learning Perl on Win32 Systems
- Programming Perl
- Advance Perl Programming
- Perl Cookbook
Для тех, кого заинтересовала эта информация, даю ссылку прямо на книги:
http://rtfm.vn.ua/prog/perl/orb/books/perl/index.html
О рассылке
В связи с тем, что ко мне часто приходят письма вновь подписавшихся с просьбой выслать предыдущие номера рассылки или указать где их можно взять, я даю адреса на subscribe.ru связанные с моей рассылкой.
Домашняя страница этой рассылки в Каталоге subscribe.ru: http://subscribe.ru/catalog/comp.soft.prog.perlprog/, здесь же Вы можете и подписаться на данную рассылку.
Архив этой рассылки находится на subscribe.ru по адресу: http://subscribe.ru/archive/comp.soft.prog.perlprog/
Данная рассылка распространяется только через subscribe.ru.
Если Вам понравилась эта рассылка, и Вы считаете, что она может быть полезна и другим, то отправьте ее
своим друзьям.
Ну, на этом позвольте на сегодня закончить. До новых встреч в новом тысячелетии.
P. S. Еще раз поздравляю всех с наступающим Новым Годом.
http://subscribe.ru/
E-mail: ask@subscribe.ru |
|
В избранное | ||