<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ZetBlog&#187; lizz</title>
	<atom:link href="http://zetblog.ru/author/lizz/feed/" rel="self" type="application/rss+xml" />
	<link>http://zetblog.ru</link>
	<description>Зеты говорят. Блог о программировании, администрировании и безопасности.</description>
	<lastBuildDate>Sat, 29 Oct 2011 18:59:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Zsh: страдаем фигнёй вместе с zsh.</title>
		<link>http://zetblog.ru/administration/201006/zsh-simple-customization/</link>
		<comments>http://zetblog.ru/administration/201006/zsh-simple-customization/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 17:07:52 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[Unix-like]]></category>
		<category><![CDATA[Администрирование]]></category>
		<category><![CDATA[shell]]></category>
		<category><![CDATA[zsh]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=1036</guid>
		<description><![CDATA[Для тех, кто не в курсе, zsh &#8212; это такой shell-интерпретатор, наподобие bash и ему подобных. Привычка его ставить пошла от FreeBSD, где дефолтные tcsh и csh совсем не юзер-френдли на мой взгляд. Может и их можно настроить до нормального уровня, но ведь настоящие герои всегда идут в обход :). Итак, в zsh можно включить [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://zetblog.ru/wp-content/uploads/2010/06/zsh.png"><img class="alignright size-medium wp-image-1041" title="zsh" src="http://zetblog.ru/wp-content/uploads/2010/06/zsh-300x44.png" alt="цветной zsh" width="300" height="44" /></a>Для тех, кто не в курсе, zsh &#8212; это такой shell-интерпретатор, наподобие bash и ему подобных. Привычка его ставить пошла от FreeBSD, где дефолтные tcsh и csh совсем не юзер-френдли на мой взгляд. Может и их можно настроить до нормального уровня, но ведь настоящие герои всегда идут в обход :).</p>
<p>Итак, в zsh можно включить достаточно мощный автокомплит просто &#171;тыкнув пару кнопок&#187; в консоли после первого запуска. Однако, по сравнению с большинством дефолтных поставок bash&#8217;а в разных дистрибутивах линукса, ему всё же не хватает цветастости. Но это дело легко поправимо, если добавить в файлик ~/.zshrc следующие алиасы:</p>
<pre class="brush: bash"># color
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors &amp;&amp; eval "$(dircolors -b ~/.dircolors)" || eval "$(dirc$
    alias ls='ls --color=auto'
    alias dir='dir --color=auto'
    alias vdir='vdir --color=auto'
    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi</pre>
<p>После этого необходимо перезапустить сеанс консоли (зайти заново в систему, запустить ещё одну копию zsh или перезапустить графический терминал &#8212; terminal, konsole, etc) и можно наслаждаться цветным выводом команд grep, ls и всего прочего описанного.</p>
<p>Не мог на этом просто взять и остановиться, ибо страдание фигнёй штука затягивающая. Дальше приделал следующую вещь:<br />
<span id="more-1036"></span></p>
<pre class="brush: bash">RPS1="(%*) %(?.:).:()"
PS1="[$(print '%{\e[1;32m%}%n%{\e[0m%}@%{\e[1;36m%}%M%{\e[0m%}') %~]$ "</pre>
<p>Переменная PS1 отвечает за строку приглашения консоли и появляется левее от курсора, RPS1 &#8212; правее. Данный код выводит в левой части разукрашенное &#171;[ имя_пользователя_@имя_хоста текущий/путь]$ &#171;, справа &#8212; &#171;(время) смайлик&#187;. Просто вставить смайлик было бы глупо, поэтому это особенный смайлик. При успешном выполнении команды он улыбается, при неудачном &#8212; огорчается :).</p>
<p>Дальше я решил что дел полно, а возиться с zsh можно вечно и пора бы уже остановиться. Если у кого-то вызовет любопытство кастомизация zsh, то можно расписать подробнее об этом.</p>
<p>P.S. Было бы интересно посмотреть на чужие конфиги ;).</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/administration/201006/zsh-simple-customization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python: Маленькая хитрость. if-else vs and-or.</title>
		<link>http://zetblog.ru/programming/201003/python-if-else-vs-and-or/</link>
		<comments>http://zetblog.ru/programming/201003/python-if-else-vs-and-or/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 19:30:57 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[общие вопросы]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[hints]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=980</guid>
		<description><![CDATA[На этот раз будет мини-заметка, уж слишком мне понравился трюк, о котором пойдёт речь дальше :). Наверное любому программисту приходится часто писать конструкции такого вида: if a == b: c = d else: c = e Как-то разбирая исходники какого-то проекта наткнулся на весьма компактную замену. Вот для сравнения два аналогичных блока кода с использованием [...]]]></description>
			<content:encoded><![CDATA[<p>На этот раз будет мини-заметка, уж слишком мне понравился трюк, о котором пойдёт речь дальше :). </p>
<p>Наверное любому программисту приходится часто писать конструкции такого вида:</p>
<pre class=".brush: python">if a == b:
    c = d
else:
    c = e</pre>
<p>Как-то разбирая исходники какого-то проекта наткнулся на весьма компактную замену. Вот для сравнения два аналогичных блока кода с использованием логических операций python&#8217;а и с использованием конструкции if-else:</p>
<pre class=".brush: python"># if-else:
if random.random() > 0.5:
    a = 1
else:
    a = 0

# and-or style:
a = random.random() > 0.5 and 1 or 0</pre>
<p>На мой взгляд выглядит гораздо лучше и компактнее (да-да, if-else можно записать в 2 строчки вместо 4, но мне так не нравится ^__^) . Другое дело, что некоторым это может показаться противоречиво с некоторыми пунктами дзена python&#8217;а (import this), но это спорно :). В общем использую там, где считаю нужным.</p>
<p>Кстати, если кого-то интересует производительность, то она примерно одинакова, далее выложу тесты и объяснение логики для тех, кому интересно.<br />
<span id="more-980"></span></p>
<pre class=".brush: python">>>> import timeit
>>> t1 = timeit.Timer('if random.random()>0.5:a=1\nelse:a =0', 'from __main__ import a\nimport random')
>>> t2 = timeit.Timer('a=random.random()>0.5 and 1 or 0', 'from __main__ import a\nimport random')
>>> t1.repeat()
[0.21074632467116317, 0.2097615509806019, 0.20978293771349854]
>>> t2.repeat()
[0.21944338095772764, 0.21785226684687586, 0.21940797240040411]
</pre>
<p>Тесты привёл, теперь объяснение.</p>
<p>Дело в том, что логические операции <strong>and</strong> и <strong>or</strong> в python&#8217;е возвращают один из операндов. Операция and возвращает первый операнд, если он приводится к логическому типу False, иначе &#8212; второй. Операция or наоборот, возвращает 1й операнд, если он приводится к типу True, иначе &#8212; второй. Всё это связано с &#171;ленивостью&#187; (lazy) операций, вычисляется столько аргументов, сколько надо для того, чтобы однозначно определить результат (например, 1 or x всегда даёт True, поэтому x не вычисляется).</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/programming/201003/python-if-else-vs-and-or/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>WordPress: Модернизация плагина statpress.</title>
		<link>http://zetblog.ru/programming/201002/wordpress-statpress-russian-optimization/</link>
		<comments>http://zetblog.ru/programming/201002/wordpress-statpress-russian-optimization/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 09:59:08 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[StatPress]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=948</guid>
		<description><![CDATA[Статистика &#8212; вещь не только интересная, но иногда и полезная :). WordPress &#8212; один из популярнейших движков php для блогов, для него существует огромное количество плагинов, в том числе и плагины для просмотра статистики по посещаемости. Один из таких плагинов &#8212; statpress. Но есть в нём некоторые недостатки, автор плагина добавил распознавание некоторых русских поисковых [...]]]></description>
			<content:encoded><![CDATA[<p>Статистика &#8212; вещь не только интересная, но иногда и полезная :). WordPress  &#8212; один из популярнейших движков php для блогов, для него существует огромное количество плагинов, в том числе и плагины для просмотра статистики по посещаемости. Один из таких плагинов &#8212; statpress. Но есть в нём некоторые недостатки, автор плагина добавил распознавание некоторых русских поисковых движков, но так же некоторые упустил из виду. Хотя даже тот же Яндекс обрабатывается не очень хорошо, не учитываются переходы с yandex.ua, yandex.kz и т.п. Но opensource тем и хорош, что всегда можно поправить исходники, если что-то тебя не устраивает :). Далее пойдёт речь об оптимизации плагина statpress под Российские поисковики.<br />
<span id="more-948"></span></p>
<p>В общем надоело мне то, что не учитывается часть поисковиков, надоело смотреть на ссылки с этих поисковиков в &#171;последних ссылающихся ресурсах&#187;, как оказалось, подправить это доваольно легко. С недельку ещё последил для отлова поисковых движков, и вот примерный список улучшений:</p>
<ul>
<li><strong>Yandex</strong> &#8212; улучшено поддержка (теперь распознаётся yandex.kz, yandex.ua. В общем то теперь маска для яндекса выглядит так: yandex.*, в связи с этим так же распознаются переходы вида yandex.ru/schoolsearch?text=* и т.п.);</li>
<li><strong>Nigma</strong> &#8212; добавлена поддержка поисковика nigma.ru</li>
<li><strong>Go Mail.ru</strong> &#8212; добавлена поддержка поисковика Go от Mail.Ru</li>
<li><strong>QIP</strong> &#8212; добавлена поддержка поисковика от QIP&#8217;а</li>
<li><strong>bing.</strong> &#8212; добавлен поисковик bing.com</li>
<li><strong>Rambler</strong> &#8212; улучшена поддержка поисковика от Рамблера</li>
</ul>
<p>Так же из &#171;ссылающихся ресурсов&#187; убараны ссылки вида &#171;*google.*&#187;, если это нововведение вам не нужно, не заменяйте в своём плагине файл statpress.php. У меня почему-то появилась куча ссылок на меня с гугла, по которым находится что-то вроде &#171;ресурс zetblog.ru пытается перенаправить вас&#187;. В случае обновления statpress.php такая проблема исчезнет, но могут так же пропасть и нужные ссылки с google (если они есть вообще).</p>
<p>После обновления файлов плагина необходимо обновить БД статистики (достаточно долгий процесс&#8230; особенно если база большая), делается это через админку wordpress путём одинарного клика по кнопке StatPressUpdate ^__^.</p>
<p>Если что-то какие-то поисковики упустил &#8212; пишите в комменты, обновлю. Ну, либо сам, если узнаю об этом :). Надеюсь, кому-то это поможет.</p>
<p>Ссылки на скачивание всего этого:<br />
<a href="http://depositfiles.com/files/3lujgxn3d">http://depositfiles.com/files/3lujgxn3d</a> &#8212; плагин полностью на депозите.<br />
Позже (по первой просьбе или как дойдут руки)) добавлю ссылку на скачивание с этого ресурса.</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/programming/201002/wordpress-statpress-russian-optimization/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Hibernate: Удаление объектов из БД.</title>
		<link>http://zetblog.ru/programming/201002/hibernate-%d1%83%d0%b4%d0%b0%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d0%be%d0%b1%d1%8a%d0%b5%d0%ba%d1%82%d0%be%d0%b2-%d0%b8%d0%b7-%d0%b1%d0%b4/</link>
		<comments>http://zetblog.ru/programming/201002/hibernate-%d1%83%d0%b4%d0%b0%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d0%be%d0%b1%d1%8a%d0%b5%d0%ba%d1%82%d0%be%d0%b2-%d0%b8%d0%b7-%d0%b1%d0%b4/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 10:35:29 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Jython]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=921</guid>
		<description><![CDATA[По работе пришлось изучать работу Java&#8217;вского ORM&#8217;а, пока что знаком только бегло, но некоторые полезные штуки для новичка решил записать. Может кому пригодится, может нет, но хотя бы самому гуглить придётся меньше =). Кстати, примеры будут не на Java, а на Jython&#8217;е, т.к. с первым я тоже не очень знаком :). Итак, опустим настройку и [...]]]></description>
			<content:encoded><![CDATA[<p>По работе пришлось изучать работу Java&#8217;вского ORM&#8217;а, пока что знаком только бегло, но некоторые полезные штуки для новичка решил записать. Может кому пригодится, может нет, но хотя бы самому гуглить придётся меньше =). Кстати, примеры будут не на Java, а на Jython&#8217;е, т.к. с первым я тоже не очень знаком :).</p>
<p>Итак, опустим настройку и подключение Hibernate, предположим, что вы это уже сделали :). Быть может, напишу об этом позже. Требуется удалить из таблицы player (которая маппится с классом Player, естественно&#8230; или наоборот :) ) некоторые записи. Если мы знаем id игрока, тогда всё элементарно (как и в других случаях)):</p>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;">player = session.<span class="me1">load</span><span class="br0">&#40;</span>Player, player_id<span class="br0">&#41;</span><br />
session.<span class="me1">delete</span><span class="br0">&#40;</span>player<span class="br0">&#41;</span></div>
</div>
<p>Теперь рассмотрим случай, когда надо удалить много записей.<span id="more-921"></span></p>
<p>В ORM&#8217;е Hibernate несколько способов провернуть это. 1й &#8212; очевидный, с помощью createQuery выбрать все нужные записи HQL&#8217;ом и в цикле удалять по одной:</p>
<pre>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;">players_list = session.<span class="me1">createQuery</span><span class="br0">&#40;</span><span class="st0">&quot;FROM Player WHERE name = :name&quot;</span><span class="br0">&#41;</span>\
&nbsp; &nbsp; .<span class="me1">setParameter</span><span class="br0">&#40;</span><span class="st0">&quot;name&quot;</span>, <span class="st0">&quot;Василий&quot;</span><span class="br0">&#41;</span>\
&nbsp; &nbsp; .<span class="kw2">list</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
<span class="kw1">for</span> player <span class="kw1">in</span> players_list:
&nbsp; &nbsp; session.<span class="me1">delete</span><span class="br0">&#40;</span>player<span class="br0">&#41;</span></div>
</div>
</pre>
<p>Но это влечёт накладные расходы на получение всех нужных объектов, а затем удаление по одному, в таком случае мы выполним столько sql-запросов, сколько объектов загрузили, что может ухудшить производительность приложения. Для этого есть другой способ. Вот в общем то и он:</p>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;">session.<span class="me1">createQuery</span><span class="br0">&#40;</span><span class="st0">&quot;DELETE Player WHERE name = :name&quot;</span><span class="br0">&#41;</span>\<br />
&nbsp; &nbsp; .<span class="me1">setParameter</span><span class="br0">&#40;</span><span class="st0">&quot;name&quot;</span>, <span class="st0">&quot;Василий&quot;</span><span class="br0">&#41;</span>\<br />
&nbsp; &nbsp; .<span class="me1">executeUpdate</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</div>
<p>Вот таким способом можно избавиться от всех неугодных нам Василиев ;). Так же есть возможность воспользоваться сырым sql с помощью Session.createSQLQuery().</p>
<p>Ссылки:<br />
<a href="http://docs.jboss.org/hibernate/stable/core/reference/en/html/batch.html#batch-direct">Документация по Hibernate</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/programming/201002/hibernate-%d1%83%d0%b4%d0%b0%d0%bb%d0%b5%d0%bd%d0%b8%d0%b5-%d0%be%d0%b1%d1%8a%d0%b5%d0%ba%d1%82%d0%be%d0%b2-%d0%b8%d0%b7-%d0%b1%d0%b4/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Python: Реализация простого web-сервера.</title>
		<link>http://zetblog.ru/programming/200911/python-simple-web-server/</link>
		<comments>http://zetblog.ru/programming/200911/python-simple-web-server/#comments</comments>
		<pubDate>Mon, 02 Nov 2009 16:26:00 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[web]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[BaseHTTPServer]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=757</guid>
		<description><![CDATA[Не для собственных нужд, но как-то понадобилось написать простой web-сервер для обработки на нём загруженных данных. В общем-то должен был получиться простой вёб-интерфейс к программе. Он и получился, местами даже слишком простой. В общем суть такова &#8212; необходимо получить от пользователя экзешник, на сервере его обработать нужными программами и выдать результат, т.е. обработанный файл для [...]]]></description>
			<content:encoded><![CDATA[<p>Не для собственных нужд, но как-то понадобилось написать простой web-сервер для обработки на нём загруженных данных. В общем-то должен был получиться простой вёб-интерфейс к программе. Он и получился, местами даже слишком простой. В общем суть такова &#8212; необходимо получить от пользователя экзешник, на сервере его обработать нужными программами и выдать результат, т.е. обработанный файл для скачивания. Можно было бы написать скрипт на php, что было бы проще, но тогда необходимо с собой таскать какой-нибудь вёб-сервер (apache, denwer и т.п.). На питоне можно его реализовать достаточно просто в самом скрипте используя стандартные заготовки и библиотеки, такие как BaseHTTPServer. Ниже следует листинг с краткими комментариями.<br />
<span id="more-757"></span></p>
<pre>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;"><span class="co1"># -*- coding: utf-8 -*-</span>

<span class="kw1">import</span> <span class="kw3">cgi</span>
<span class="kw1">from</span> <span class="kw3">os</span> <span class="kw1">import</span> curdir, sep
<span class="kw1">from</span> <span class="kw3">BaseHTTPServer</span> <span class="kw1">import</span> BaseHTTPRequestHandler, HTTPServer
<span class="kw1">import</span> <span class="kw3">subprocess</span>

<span class="kw1">class</span> MyHandler<span class="br0">&#40;</span>BaseHTTPRequestHandler<span class="br0">&#41;</span>:
&nbsp; &nbsp; <span class="kw1">def</span> do_GET<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="kw2">self</span>.<span class="me1">path</span> <span class="sy0">!</span>= <span class="st0">&quot;/output.exe&quot;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f = <span class="kw2">open</span><span class="br0">&#40;</span>curdir+sep+<span class="st0">&quot;upload.html&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">send_response</span><span class="br0">&#40;</span>200<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">send_header</span><span class="br0">&#40;</span><span class="st0">&quot;Content-type&quot;</span>, <span class="st0">&quot;text/html&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">end_headers</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">wfile</span>.<span class="me1">write</span><span class="br0">&#40;</span>f.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">send_response</span><span class="br0">&#40;</span>200<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">send_header</span><span class="br0">&#40;</span><span class="st0">&quot;Content-type&quot;</span>, <span class="st0">&quot;application/octet-stream&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">end_headers</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">wfile</span>.<span class="me1">write</span><span class="br0">&#40;</span><span class="kw2">open</span><span class="br0">&#40;</span>curdir+sep+<span class="st0">&quot;output.exe&quot;</span>, <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">IOError</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">send_error</span><span class="br0">&#40;</span><span class="nu0">404</span>,<span class="st0">&quot;File Not Found: %s&quot;</span> <span class="sy0">%</span> <span class="kw2">self</span>.<span class="me1">path</span><span class="br0">&#41;</span>

&nbsp; &nbsp; <span class="kw1">def</span> do_POST<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">try</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ctype, pdict = <span class="kw3">cgi</span>.<span class="me1">parse_header</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">headers</span>.<span class="me1">getheader</span><span class="br0">&#40;</span><span class="st0">&quot;content-type&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> ctype == <span class="st0">&quot;multipart/form-data&quot;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; query = <span class="kw3">cgi</span>.<span class="me1">parse_multipart</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">rfile</span>, pdict<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">send_response</span><span class="br0">&#40;</span>200<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">end_headers</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; upfile = query.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;file&quot;</span><span class="br0">&#41;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f = <span class="kw2">open</span><span class="br0">&#40;</span>curdir+sep+<span class="st0">&quot;output.exe&quot;</span>, <span class="st0">&quot;wb&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f.<span class="me1">write</span><span class="br0">&#40;</span>upfile<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; params = <span class="st0">&quot; np output.exe&quot;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p = query.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;encryption&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> p<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> == <span class="st0">&quot;aes&quot;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; params += <span class="st0">&quot; sf 1&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elif</span> p<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> == <span class="st0">&quot;rc5&quot;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; params += <span class="st0">&quot; sf 2&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">elif</span> p<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> == <span class="st0">&quot;xor&quot;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; params += <span class="st0">&quot; sf 3&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; params += <span class="st0">&quot; sf 0&quot;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p = query.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;hw_bind&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> p<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> == <span class="st0">&quot;yes&quot;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p = query.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;hw_bind_serial&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">assert</span> <span class="kw2">len</span><span class="br0">&#40;</span>p<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span> == <span class="nu0">8</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; params += <span class="st0">&quot; sn &quot;</span> + p<span class="br0">&#91;</span>0<span class="br0">&#93;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; params += <span class="st0">&quot; sn 0&quot;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p = query.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;passwd&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">assert</span> <span class="kw2">len</span><span class="br0">&#40;</span>p<span class="br0">&#91;</span>0<span class="br0">&#93;</span><span class="br0">&#41;</span> <span class="sy0">&amp;</span>gt<span class="sy0">;</span> <span class="nu0">0</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; params += <span class="st0">&quot; pass &quot;</span> + p<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; p = query.<span class="me1">get</span><span class="br0">&#40;</span><span class="st0">&quot;pack&quot;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> p<span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span> == <span class="st0">&quot;yes&quot;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; params += <span class="st0">&quot; pack 1&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; params += <span class="st0">&quot; pack 0&quot;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pipe = <span class="kw3">subprocess</span>.<span class="me1">Popen</span><span class="br0">&#40;</span><span class="st0">&quot;processor.exe &quot;</span>+params, shell=<span class="kw2">True</span>, stdin=<span class="kw3">subprocess</span>.<span class="me1">PIPE</span>, stdout=<span class="kw3">subprocess</span>.<span class="me1">PIPE</span>, stderr=<span class="kw3">subprocess</span>.<span class="me1">PIPE</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pipe.<span class="me1">stdin</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pipe.<span class="me1">wait</span><span class="br0">&#40;</span><span class="br0">&#41;</span>

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">wfile</span>.<span class="me1">write</span><span class="br0">&#40;</span><span class="st0">'&lt;a href=&quot;/output.exe&quot;&gt;Download results&lt;/a&gt;.'</span><span class="br0">&#41;</span><span class="sy0">;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">except</span> :
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">pass</span>

<span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:
&nbsp; &nbsp; <span class="kw1">try</span>:
&nbsp; &nbsp; &nbsp; &nbsp; server = HTTPServer<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span>, 8080<span class="br0">&#41;</span>, MyHandler<span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;started httpserver...&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; server.<span class="me1">serve_forever</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; <span class="kw1">except</span> <span class="kw2">KeyboardInterrupt</span>:
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">print</span> <span class="st0">&quot;^C received, shutting down server&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; server.<span class="kw3">socket</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div>
</div>
</pre>
<p>Итак, для начала импортируем из библиотеки BaseHTTPServer два класса: HTTPserver — собственно, сам вёб-сервер и BaseHTTPRequestHandler — класс, который служит для обработки запросов от пользователей.</p>
<p>Объявляем свой класс MyHandler, который наследуется от BaseHTTPRequestHandler. И перегружаем в нём два метода — do_GET и do_POST для обработки данных, переданных методом GET и POST, соответственно.</p>
<p>В первом обработчике проверяем запрос от пользователя (содержится в  self.path), если запрашиваемый документ не является /output.exe, то выдаём форму для загрузки файла, иначе — считываем и выдаём output.exe. Так же, перед этим, посылается ответ от сервера с кодом 200, что соответствует успешной обработке запроса от клиента и передаём заголовок, в котором указан тип содержимого (text/html для html-код или application/octet-stream для бинарного файла).</p>
<p>В обработке POST-запроса проверяем какие данные были переданы. Сначала получаем файл и записываем его под именем output.exe. Далее формируем строку параметров на основе переданных от пользователя данных, запускаем хранящуюся на сервере программу для обработки полученных файлов, ждём пока она завершится и выдаём ссылку на скачивание результата.</p>
<p>Далее, в самой программе создаём вёб-сервер, указав при этом порт, на котором он будет работать (в примере это 8080) и класс, который необходимо использовать для обработки запросов от пользователей.</p>
<p>Недостаток заключается в том, что данная реализация не сможет обработать одновременную загрузку файлов от разных пользователей, т.к. в лучшем случае просто один из запросов затрёт файл output.exe, полученный в другом запросе. Но такая задача не стояла. На мой взгляд хороший пример для демонстрации возможностей python&#8217;а.</p>
<p>Так же код html-файла upload.html, который должен располагаться в той же директории, что и сервер:</p>
<pre>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc2">&lt;<a href="http://december.com/html/4/element/form.html"><span class="kw2">form</span></a> <span class="kw3">action</span><span class="sy0">=</span><span class="st0">&quot;/&quot;</span> <span class="kw3">enctype</span><span class="sy0">=</span><span class="st0">&quot;multipart/form-data&quot;</span> <span class="kw3">method</span><span class="sy0">=</span><span class="st0">&quot;post&quot;</span>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/table.html"><span class="kw2">table</span></a> <span class="kw3">border</span><span class="sy0">=</span><span class="st0">&quot;1&quot;</span>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/tbody.html"><span class="kw2">tbody</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/tr.html"><span class="kw2">tr</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>Encryption:<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">checked</span><span class="sy0">=</span><span class="st0">&quot;checked&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;encryption&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;radio&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;none&quot;</span> <span class="sy0">/</span>&gt;</span>None
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;encryption&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;radio&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;aes&quot;</span> <span class="sy0">/</span>&gt;</span>AES
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;encryption&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;radio&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;rc5&quot;</span> <span class="sy0">/</span>&gt;</span>RC5
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;encryption&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;radio&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;xor&quot;</span> <span class="sy0">/</span>&gt;</span>XOR<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/tr.html"><span class="kw2">tr</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/tr.html"><span class="kw2">tr</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>Hardware binding:<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">checked</span><span class="sy0">=</span><span class="st0">&quot;checked&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;hw_bind&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;radio&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;no&quot;</span> <span class="sy0">/</span>&gt;</span>No
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;hw_bind&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;radio&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;yes&quot;</span> <span class="sy0">/</span>&gt;</span>Yes
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;hw_bind_serial&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;media serial number&quot;</span> <span class="sy0">/</span>&gt;&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/tr.html"><span class="kw2">tr</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/tr.html"><span class="kw2">tr</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>Password:<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;passwd&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;password&quot;</span> <span class="sy0">/</span>&gt;&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/tr.html"><span class="kw2">tr</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/tr.html"><span class="kw2">tr</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>Pack:<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">checked</span><span class="sy0">=</span><span class="st0">&quot;checked&quot;</span> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;pack&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;radio&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;no&quot;</span> <span class="sy0">/</span>&gt;</span>No
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;pack&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;radio&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;yes&quot;</span> <span class="sy0">/</span>&gt;</span>Yes<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/tr.html"><span class="kw2">tr</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/tr.html"><span class="kw2">tr</span></a>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a> <span class="kw3">colspan</span><span class="sy0">=</span><span class="st0">&quot;2&quot;</span>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">name</span><span class="sy0">=</span><span class="st0">&quot;file&quot;</span> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;file&quot;</span> <span class="sy0">/</span>&gt;</span>
<span class="sc2">&lt;<a href="http://december.com/html/4/element/input.html"><span class="kw2">input</span></a> <span class="kw3">type</span><span class="sy0">=</span><span class="st0">&quot;submit&quot;</span> <span class="kw3">value</span><span class="sy0">=</span><span class="st0">&quot;Отправить&quot;</span> <span class="sy0">/</span>&gt;&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/td.html"><span class="kw2">td</span></a>&gt;</span>
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/tr.html"><span class="kw2">tr</span></a>&gt;</span>
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/tbody.html"><span class="kw2">tbody</span></a>&gt;&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/table.html"><span class="kw2">table</span></a>&gt;</span>
<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/form.html"><span class="kw2">form</span></a>&gt;</span></div>
</div>
</pre>
<p>Ссылки к статье:<br />
<a href="http://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%BA%D0%BE%D0%B4%D0%BE%D0%B2_%D1%81%D0%BE%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D1%8F_HTTP"><br />
http://ru.wikipedia.org/wiki/Список_кодов_состояния_HTTP</a> &#8212; Список кодов состояния HTTP.</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/programming/200911/python-simple-web-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Windows: Как определить модель устройства.</title>
		<link>http://zetblog.ru/administration/200911/windows-identify-device-model/</link>
		<comments>http://zetblog.ru/administration/200911/windows-identify-device-model/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 22:53:31 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[Администрирование]]></category>
		<category><![CDATA[device]]></category>
		<category><![CDATA[Windows XP]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=749</guid>
		<description><![CDATA[Иногда встаёт вопрос. И требуется ответ. Если вопрос &#8212; узнать под ОС Windows модель какого-либо подключенного устройства, то ответ можно получить следующим образом. Жмём правой кнопкой по &#171;моему компьютеру&#187; (или по Вашему, если моего рядом нет), выбираем &#171;свойства&#187;, в новом окне вкладку &#171;оборудование&#187;, &#171;диспетчер устройств&#187;. Находим в списке нужное устройство (аудиоконтроллер, сетевая карточка, etc), опять [...]]]></description>
			<content:encoded><![CDATA[<p>Иногда встаёт вопрос. И требуется ответ. Если вопрос &#8212; узнать под ОС Windows модель какого-либо подключенного устройства, то ответ можно получить следующим образом. Жмём правой кнопкой по &#171;моему компьютеру&#187; (или по Вашему, если моего рядом нет), выбираем &#171;свойства&#187;, в новом окне вкладку &#171;оборудование&#187;, &#171;диспетчер устройств&#187;. Находим в списке нужное устройство (аудиоконтроллер, сетевая карточка, etc), опять жмём правой кнопкой мыши по нужному девайсу, переходим на вкладку &#171;сведения&#187; и ищем подпункт &#171;код экземпляра устройства&#187;, который может выглядеть следующим образом:</p>
<div class="codesnip-container" >PCI\VEN_XXX&amp;DEV_XXXX&amp;SUBSYS_XXXXXXXX</div>
<p><span id="more-749"></span></p>
<p>Ну, или примерно так. В общем то это всё, что нам надо, далее идём в гугл и вводим коды строку вида &#171;VEN XXXX DEV XXXX&#187;, где XXXX &#8212; соответственно коды производителя и самого устройства. Далее несложно будет найти какому девайсу и модели эти коду соответствуют.</p>
<p>Для тех, кто мало чего понял, картинка:<br />
<a href="http://zetblog.ru/wp-content/uploads/2009/11/PCI_VEN.png"><img src="/wp-content/uploads/2009/11/PCI_VEN-150x150.png" alt="Диспетчер устройств Windows" /></a></p>
<p>Если кто знает более простой способ, то буду рад услышать ;).</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/administration/200911/windows-identify-device-model/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Python: Проблема с подвисанием GUI на TkInter.</title>
		<link>http://zetblog.ru/programming/200910/python-tkinter-antifreeze/</link>
		<comments>http://zetblog.ru/programming/200910/python-tkinter-antifreeze/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 18:57:03 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[общие вопросы]]></category>
		<category><![CDATA[прикладное]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[GUI]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[TkInter]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=731</guid>
		<description><![CDATA[Встала задача написания небольшой графической оболочки для программы с минимальным интерфейсом (одна кнопка и одно поле вывода). Много нам не надо, поэтому решил обойтись идущей вместе с python&#8217;ом в поставке библиотекой TkInter. И тут столкнулся с небольшой проблемой &#8212; при нажатии кнопки запускаются довольно долгие и объёмные вычисления, из-за которых виснет весь интерфейс программы. Решений [...]]]></description>
			<content:encoded><![CDATA[<p>Встала задача написания небольшой графической оболочки для программы с минимальным интерфейсом (одна кнопка и одно поле вывода). Много нам не надо, поэтому решил обойтись идущей вместе с python&#8217;ом в поставке библиотекой TkInter. И тут столкнулся с небольшой проблемой &#8212; при нажатии кнопки запускаются довольно долгие и объёмные вычисления, из-за которых виснет весь интерфейс программы.<br />
<span id="more-731"></span></p>
<p>Решений у этого вопроса несколько.<br />
1 &#8212; Запускать эти вычисления в отдельном потоке, что меня вполне устроило:</p>
<pre>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;"><span class="co1"># -*- coding: utf-8 -*-</span>
<span class="kw1">from</span> <span class="kw3">Tkinter</span> <span class="kw1">import</span> <span class="sy0">*</span>
<span class="kw1">import</span> <span class="kw3">threading</span>, <span class="kw3">time</span>

<span class="kw1">class</span> AppGUI:
&nbsp; &nbsp; <span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">tk</span> = Tk<span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; frame = Frame<span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">tk</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; frame.<span class="me1">pack</span><span class="br0">&#40;</span><span class="br0">&#41;</span>
&nbsp; &nbsp; &nbsp; &nbsp; Button<span class="br0">&#40;</span>frame, text=<span class="st0">&quot;Compute&quot;</span>, command=<span class="kw2">self</span>.<span class="me1">computeWithGUIAntifreeze</span><span class="br0">&#41;</span>.<span class="me1">pack</span><span class="br0">&#40;</span><span class="br0">&#41;</span>

&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">def</span> run<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">self</span>.<span class="me1">tk</span>.<span class="me1">mainloop</span><span class="br0">&#40;</span><span class="br0">&#41;</span>

&nbsp; &nbsp; <span class="kw1">def</span> computeWithGUIAntifreeze<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;&quot; Метод-прокладка для запуска в новом потоке вычислений &quot;&quot;&quot;</span>
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">threading</span>.<span class="me1">Thread</span><span class="br0">&#40;</span>target=<span class="kw2">self</span>.<span class="me1">compute</span><span class="br0">&#41;</span>.<span class="me1">start</span><span class="br0">&#40;</span><span class="br0">&#41;</span>

&nbsp; &nbsp; <span class="kw1">def</span> compute<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:
&nbsp; &nbsp; &nbsp; &nbsp; <span class="st0">&quot;&quot;&quot;&quot; Тут как раз и происходят длительные вычисления &quot;&quot;&quot;</span><span class="st0">&quot;
&nbsp; &nbsp; &nbsp; &nbsp; time.sleep(15)

gui = AppGUI()
gui.run()</span></div>
</div>
</pre>
<p>2 &#8212; Использовать время от времени методы:</p>
<ul>
<li><strong>Tk.update()</strong>;</li>
<li><strong>Tk.update_idletasks()</strong> &#8212; только обновляет окна, но не вызывает обработку событий, сгенерированных пользователем, в отличие от Tk.update();</li>
</ul>
<p>Использовать эти методы стоит с осторожностью, дабы не возникло неприятных ситуаций (подробнее в документации). Таково предостережение официальной документации.</p>
<p>Ссылки к посту:<br />
<a href="http://www.tcl.tk/man/tcl8.5/TclCmd/update.htm">http://www.tcl.tk/man/tcl8.5/TclCmd/update.htm</a> &#8212; официальная документация по Tcl/Tk.</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/programming/200910/python-tkinter-antifreeze/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python: генератор списка паролей для перебора (brute-force).</title>
		<link>http://zetblog.ru/programming/200910/python-passwords-list-for-bruteforce/</link>
		<comments>http://zetblog.ru/programming/200910/python-passwords-list-for-bruteforce/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 11:56:19 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[прикладное]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Brute Force]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=716</guid>
		<description><![CDATA[При написании в очередной раз программы для подбора паролей к чему-либо (исключительно в образовательных целях и для учёбы ;-) ) опять возникла необходимость в итераторе по заданному алфавиту. Т.е. необходимо написать класс, который мог бы генерировать пароли для последующей передачи их в программу, которая &#171;примеряла&#187; их к чему-надо. К чему &#8212; дело третье и сейчас [...]]]></description>
			<content:encoded><![CDATA[<p>При написании в очередной раз программы для подбора паролей к чему-либо (исключительно в образовательных целях и для учёбы ;-) ) опять возникла необходимость в итераторе по заданному алфавиту. Т.е. необходимо написать класс, который мог бы генерировать пароли для последующей передачи их в программу, которая &#171;примеряла&#187; их к чему-надо. К чему &#8212; дело третье и сейчас нас (вернее Вас) не волнует. В результате получился скромный класс, который приведён ниже со столь же скромными моими комментариями к нему :-).<br />
<span id="more-716"></span></p>
<p>Сам класс для перебора паролей ко всему и вся таков:</p>
<pre class="brush: python"># -*- coding: utf-8 -*-

EN = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
en = "abcdefghijklmnopqrstuvwxyz"
RU = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
ru = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя"
digits = "1234567890"
space = " "
p = ",.-!?;:'\"/()"
op = "+-*/:^()&lt;&gt;="
all_spec = "`~!@#$%^&amp;*-_=+\\|/?.&gt;,&lt; '\";:[]{}"

class ABCIterator:
    firstuse_flag = True
    stop = None

    def __init__(self, start="", stop=None, start_len=None, stop_len=None, abc=en+EN+digits+all_spec):
        assert len(abc) &gt; 0
        if start_len is not None:
            assert start_len &gt; 0
            #assert start == ""
            self.current_str = list(abc[0]*start_len)
        else:
            self.current_str = list(filter(lambda x: x in abc, start))
        if stop_len is not None:
            assert (start_len is None) or (start_len &lt;= stop_len)
            assert stop_len &gt; 0
            self.stop = list(abc[0]*(stop_len+1)) # т.к. итератор работает с полуотрезками
        else:
            if stop is not None: self.stop = list(filter(lambda x: x in abc, stop))
        self.abc = list(abc)

    def __iter__(self):
        return self

    def next(self):
        if (self.stop is not None) and (self.stop == self.current_str):
            raise StopIteration
        if self.current_str == []:
            self.current_str.append(self.abc[0])
            self.firstuse_flag = False
            return self.abc[0]
        elif self.firstuse_flag:
            self.firstuse_flag = False
            return "".join(self.current_str)
        offset = 0
        while offset &lt; len(self.current_str):
            if self.current_str[offset] != self.abc[-1]:
                self.current_str[offset] = self.abc[self.abc.index(self.current_str[offset])+1]
                # выпендрёшь для полуотрезка
                if (self.stop is not None) and (self.current_str == self.stop):
                    raise StopIteration
                return "".join(self.current_str)
            self.current_str[offset] = self.abc[0]
            offset += 1
        self.current_str = [self.abc[0]] + self.current_str
        # опять же оно же
        if (self.stop is not None) and (self.current_str == self.stop):
            raise StopIteration
        return "".join(self.current_str)
</pre>
<p>А таковы мои пояснения к нему:</p>
<ul>
<li><strong>firstuse_flag</strong> &#8212; свойство, которое указывает на то, что итератор используется впервые и не стоит производить итерацию, надо лишь вернуть текущее значени строки. Это нужно для того, чтобы в цикле не &#171;съедалось&#187; первое значение (напр., инициализировали итератор с начальной строкой &#171;aaa&#187;, а при 1й же итерации он вернул бы, без этого чудесного свойства, &#171;baa&#187;)</li>
<li><strong>stop</strong> &#8212; указывает на значение, на котором пора бы уже остановиться и вызвать исключение StopIteration. Если не задано (имеет значение None), то не пора, итератор будет бесконечным</li>
<li><strong>__init__(start=&#187;, stop=None, start_len=None, stop_len=None, abc=en+EN+digits+all_spec, **kwargs)</strong> &#8212; в общем то сам конструктор. <strong>start</strong> &#8212; начальное значение, <strong>stop</strong> &#8212; конечное, если не задано или идёт до начального, то итерации происходят бесконечно. Можно так же задать начальную и конечную длину, место конкретных значений с помощью <strong>start_len</strong> и <strong>stop_len</strong>. Если задана длина и начальные значения, то приоритет будет иметь длина, что можно легко исправить, если для кого-то это критично. <strong>abc</strong> &#8212; алфавит, над которым будут производиться итерации.</li>
<li><strong>__iter__()</strong> &#8212; необходимо для того чтобы класс был полноценным итератором.</li>
<li><strong>next()</strong> &#8212; возвращает следующую строку, в общем-то этот метод так же необходим для того чтобы класс был итератором.</li>
</ul>
<p>Пример использования:</p>
<pre>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;"><span class="sy0">&gt;&gt;&gt;</span> <span class="kw1">for</span> i <span class="kw1">in</span> ABCIterator<span class="br0">&#40;</span>start_len=<span class="nu0">1</span>, stop_len=<span class="nu0">3</span>, abc=<span class="st0">&quot;abc&quot;</span><span class="br0">&#41;</span>:
... &nbsp; &nbsp; <span class="me1">i</span>
...
<span class="st0">'a'</span>
<span class="st0">'b'</span>
<span class="br0">&#91;</span>...<span class="br0">&#93;</span>
<span class="st0">'bcc'</span>
<span class="st0">'ccc'</span>
<span class="sy0">&gt;&gt;&gt;</span></div>
</div>
</pre>
<p>Ну, как-то так оно и работает. Если кому-то что-то непонятно, то могу объяснить подробнее. В общем как обычно, всё в комменты ;-). Неплохо было бы ещё реализовать преобразование чисел в строки и наоборот, но это позже&#8230; может быть.</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/programming/200910/python-passwords-list-for-bruteforce/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Python: файловый интерпретатор.</title>
		<link>http://zetblog.ru/programming/200905/python-%d1%84%d0%b0%d0%b9%d0%bb%d0%be%d0%b2%d1%8b%d0%b9-%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%bf%d1%80%d0%b5%d1%82%d0%b0%d1%82%d0%be%d1%80/</link>
		<comments>http://zetblog.ru/programming/200905/python-%d1%84%d0%b0%d0%b9%d0%bb%d0%be%d0%b2%d1%8b%d0%b9-%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%bf%d1%80%d0%b5%d1%82%d0%b0%d1%82%d0%be%d1%80/#comments</comments>
		<pubDate>Wed, 20 May 2009 12:46:23 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=710</guid>
		<description><![CDATA[Очередной бестолковый велосипед от СГУ. Требуется написать &#171;интерпретатор&#187;, который умел бы работать с файлами. Так же умел бы исполнять сторонние скрипты. Работа с файлами заключается в следующих функциях &#8212; открыть на запись, открыть на чтение, закрыть файл, читать из файла, читать n байт, записать в файл, читать в буфер, записать из буфера в файл, сместиться [...]]]></description>
			<content:encoded><![CDATA[<p>Очередной бестолковый велосипед от СГУ. Требуется написать &#171;интерпретатор&#187;, который умел бы работать с файлами. Так же умел бы исполнять сторонние скрипты. Работа с файлами заключается в следующих функциях &#8212; открыть на запись, открыть на чтение, закрыть файл, читать из файла, читать n байт, записать в файл, читать в буфер, записать из буфера в файл, сместиться на определённую позицию.<br />
<span id="more-710"></span></p>
<p>По сути получается некая прослойка между консолью и функциями самого языка программирования. В C++ пришлось наверное помучиться над этим (хотя ничего сложного, главное &#8212; знания), в python&#8217;е всё как всегда ;-).</p>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;"><span class="co1">#!/usr/bin/env python</span><br />
<span class="co1"># -*- coding: utf-8 -*-</span></p>
<p><span class="kw1">import</span> <span class="kw3">sys</span></p>
<p><span class="kw1">class</span> MyFile:<br />
<span class="kw1">def</span> <span class="kw4">__init__</span><span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
<span class="kw2">self</span>.<span class="me1">name</span> = <span class="kw2">None</span><br />
<span class="kw2">self</span>.<span class="me1">desc</span> = <span class="kw2">None</span><br />
<span class="kw2">self</span>.<span class="me1">flags</span> = <span class="kw2">None</span><br />
<span class="kw2">self</span>.<span class="me1">buffer</span> = <span class="st0">&quot;&quot;</span></p>
<p><span class="kw1">def</span> <span class="kw2">open</span><span class="br0">&#40;</span><span class="kw2">self</span>, fname, flags<span class="br0">&#41;</span>:<br />
<span class="kw1">print</span> <span class="st0">&quot;Opening %s in mode %s.&quot;</span> <span class="sy0">%</span> <span class="br0">&#40;</span>fname, flags<span class="br0">&#41;</span><br />
<span class="kw2">self</span>.<span class="me1">name</span> = fname<br />
<span class="kw2">self</span>.<span class="me1">flags</span> = flags<br />
<span class="kw2">self</span>.<span class="me1">desc</span> = <span class="kw2">open</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">name</span>, flags<span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> write<span class="br0">&#40;</span><span class="kw2">self</span>, data<span class="br0">&#41;</span>:<br />
<span class="kw1">print</span> <span class="st0">&quot;Writing data in file.&quot;</span><br />
<span class="kw2">self</span>.<span class="me1">desc</span>.<span class="me1">write</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> writeFromBuffer<span class="br0">&#40;</span><span class="kw2">self</span>, <span class="kw3">bytes</span>=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
<span class="kw1">if</span> <span class="kw3">bytes</span> <span class="kw1">is</span> <span class="kw2">None</span>:<br />
<span class="kw3">bytes</span> = <span class="kw2">len</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">buffer</span><span class="br0">&#41;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;Writing data in file from buffer.&quot;</span><br />
<span class="kw2">self</span>.<span class="me1">desc</span>.<span class="me1">write</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">buffer</span><span class="br0">&#91;</span>:<span class="kw3">bytes</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;Wrote %d bytes.&quot;</span> <span class="sy0">%</span> <span class="kw2">len</span><span class="br0">&#40;</span><span class="kw2">self</span>.<span class="me1">buffer</span><span class="br0">&#91;</span>:<span class="kw3">bytes</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
<span class="kw2">self</span>.<span class="me1">buffer</span> = <span class="kw2">self</span>.<span class="me1">buffer</span><span class="br0">&#91;</span><span class="kw3">bytes</span>:<span class="br0">&#93;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> read<span class="br0">&#40;</span><span class="kw2">self</span>, <span class="kw3">bytes</span>=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
<span class="kw1">print</span> <span class="st0">&quot;Reading from file.&quot;</span><br />
<span class="kw1">if</span> <span class="kw3">bytes</span> <span class="kw1">is</span> <span class="kw2">None</span>:<br />
r = <span class="kw2">self</span>.<span class="me1">desc</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="kw1">else</span>:<br />
r = <span class="kw2">self</span>.<span class="me1">desc</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="kw3">bytes</span><span class="br0">&#41;</span><br />
lr = <span class="kw2">len</span><span class="br0">&#40;</span>r<span class="br0">&#41;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;Read %d bytes from file: <span class="es0">\&quot;</span>%s<span class="es0">\&quot;</span>.&quot;</span> <span class="sy0">%</span> <span class="br0">&#40;</span>lr, r<span class="br0">&#41;</span><br />
<span class="kw1">return</span> r</p>
<p><span class="kw1">def</span> writeToBuffer<span class="br0">&#40;</span><span class="kw2">self</span>, <span class="kw3">bytes</span>=<span class="kw2">None</span><span class="br0">&#41;</span>:<br />
<span class="kw1">print</span> <span class="st0">&quot;Reading from file to buffer.&quot;</span><br />
<span class="kw1">if</span> <span class="kw3">bytes</span> <span class="kw1">is</span> <span class="kw2">None</span>:<br />
r = <span class="kw2">self</span>.<span class="me1">desc</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="kw1">else</span>:<br />
r = <span class="kw2">self</span>.<span class="me1">desc</span>.<span class="me1">read</span><span class="br0">&#40;</span><span class="kw3">bytes</span><span class="br0">&#41;</span><br />
lr = <span class="kw2">len</span><span class="br0">&#40;</span>r<span class="br0">&#41;</span><br />
<span class="kw2">self</span>.<span class="me1">buffer</span> += r<br />
<span class="kw1">print</span> <span class="st0">&quot;Read %d bytes from file: <span class="es0">\&quot;</span>%s<span class="es0">\&quot;</span>.&quot;</span> <span class="sy0">%</span> <span class="br0">&#40;</span>lr, r<span class="br0">&#41;</span><br />
<span class="kw1">return</span> r</p>
<p><span class="kw1">def</span> clearBuffer<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
<span class="kw2">self</span>.<span class="me1">buffer</span> = <span class="st0">&quot;&quot;</span></p>
<p><span class="kw1">def</span> close<span class="br0">&#40;</span><span class="kw2">self</span><span class="br0">&#41;</span>:<br />
<span class="kw1">print</span> <span class="st0">&quot;Closing file.&quot;</span><br />
<span class="kw2">self</span>.<span class="me1">desc</span>.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> seek<span class="br0">&#40;</span><span class="kw2">self</span>, position<span class="br0">&#41;</span>:<br />
position = <span class="kw2">int</span><span class="br0">&#40;</span>position<span class="br0">&#41;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;Seting seek in file to position %d&quot;</span> <span class="sy0">%</span> position<br />
<span class="kw2">self</span>.<span class="me1">desc</span>.<span class="me1">seek</span><span class="br0">&#40;</span>position<span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> process<span class="br0">&#40;</span>f<span class="br0">&#41;</span>:<br />
f = <span class="kw2">open</span><span class="br0">&#40;</span>f, <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span><br />
mf = MyFile<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="kw1">for</span> line <span class="kw1">in</span> f:<br />
<span class="kw2">eval</span><span class="br0">&#40;</span><span class="st0">&quot;mf.&quot;</span> + line<span class="br0">&#41;</span><br />
f.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
args = <span class="kw3">sys</span>.<span class="me1">argv</span><span class="br0">&#91;</span>1:<span class="br0">&#93;</span><br />
<span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span>args<span class="br0">&#41;</span> <span class="sy0">&amp;</span>gt<span class="sy0">;</span> 0:<br />
<span class="kw1">for</span> arg <span class="kw1">in</span> args:<br />
<span class="kw1">try</span>:<br />
process<span class="br0">&#40;</span>arg<span class="br0">&#41;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;!!! %s processed successfully. !!!&quot;</span> <span class="sy0">%</span> arg<br />
<span class="kw1">except</span>:<br />
<span class="kw1">print</span> <span class="st0">&quot;!!! Error while processing script %s. !!!&quot;</span> <span class="sy0">%</span> arg<br />
<span class="kw1">else</span>:<br />
action = <span class="st0">&quot;&quot;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;q &#8212; quit&quot;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;open(fname) &#8212; open file&quot;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;write(data) &#8212; write data in file&quot;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;read([bytes]) &#8212; read data from file&quot;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;seek(position) &#8212; set seek in file to position&quot;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;close() &#8212; close file&quot;</span><br />
f = MyFile<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="kw1">while</span> <span class="kw2">True</span>:<br />
<span class="kw1">try</span>:<br />
<span class="kw2">eval</span><span class="br0">&#40;</span><span class="st0">&quot;f.&quot;</span> + <span class="kw2">raw_input</span><span class="br0">&#40;</span><span class="st0">&quot;&amp;gt; &quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="kw1">except</span>:<br />
<span class="kw1">print</span> <span class="st0">&quot;Error.&quot;</span><br />
<span class="kw1">else</span>:<br />
<span class="kw1">print</span> <span class="st0">&quot;Ok.&quot;</span></div>
</div>
<p>Если мы хотим работать в интерактивном режиме &#8212; то просто выполняем скрипт, если хотим обработать скрипты &#8212; передаём их имена в параметрах программы. Например:</p>
<div class="codesnip-container" >$./main.py 1.scr 2.scr 3.scr</div>
<p>На сегодня, пожалуй, хватит с меня постов, подожду пока эти оценят ;-).</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/programming/200905/python-%d1%84%d0%b0%d0%b9%d0%bb%d0%be%d0%b2%d1%8b%d0%b9-%d0%b8%d0%bd%d1%82%d0%b5%d1%80%d0%bf%d1%80%d0%b5%d1%82%d0%b0%d1%82%d0%be%d1%80/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python: генерация группы ключей.</title>
		<link>http://zetblog.ru/programming/200905/python-%d0%b3%d0%b5%d0%bd%d0%b5%d1%80%d0%b0%d1%86%d0%b8%d1%8f-%d0%b3%d1%80%d1%83%d0%bf%d0%bf%d1%8b-%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%b9/</link>
		<comments>http://zetblog.ru/programming/200905/python-%d0%b3%d0%b5%d0%bd%d0%b5%d1%80%d0%b0%d1%86%d0%b8%d1%8f-%d0%b3%d1%80%d1%83%d0%bf%d0%bf%d1%8b-%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%b9/#comments</comments>
		<pubDate>Wed, 20 May 2009 12:23:34 +0000</pubDate>
		<dc:creator>lizz</dc:creator>
				<category><![CDATA[криптография]]></category>
		<category><![CDATA[Программирование]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://zetblog.ru/?p=707</guid>
		<description><![CDATA[Опять делюсь универскими наработками. Задача в общем то примитивная (или по крайней мере её реализация). Надо сгенерировать N равнозначных ключей для шифрования/дешифрования сообщения. Т.е., генерируем 10 ключей, шифруем сообщение любым из этих 10, расшифровываем так же любым из этих 10. Например, зашифровали пятым ключом, расшифровали третьим, или десятым. Для реализации поставленной задачи опять прибегнем к [...]]]></description>
			<content:encoded><![CDATA[<p>Опять делюсь универскими наработками. Задача в общем то примитивная (или по крайней мере её реализация). Надо сгенерировать N равнозначных ключей для шифрования/дешифрования сообщения. Т.е., генерируем 10 ключей, шифруем сообщение любым из этих 10, расшифровываем так же любым из этих 10. Например, зашифровали пятым ключом, расшифровали третьим, или десятым.<br />
<span id="more-707"></span></p>
<p>Для реализации поставленной задачи опять прибегнем к ксору aka XOR, исключающее или, почти <a href="/programming/200812/%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%BE%D0%B3%D1%80%D0%B0%D1%84%D0%B8%D1%8F-%D1%88%D0%B8%D1%84%D1%80-%D0%B2%D0%B5%D1%80%D0%BD%D0%B0%D0%BC%D0%B0/">шифр Вернама</a>. Почти &#8212; потому что длина ключа у нас по сути не равна длине сообщения. Алгоритм будет таков:</p>
<ol>
<li>Дано начальное значение ikey. В общем то это и будет на самом деле ключ, который используется в шифровании и расшифровке, просто он будет &#171;спрятан&#187; в сгенерированных ключах.</li>
<li>Генерируем 10 случайных строк по длине равных ключу ikey.</li>
<li>Для каждой строки из предыдущего пункта выполняем: xor(A, ikey) + A. Полученные строки и будут нашими ключами.</li>
</ol>
<p>Теперь для шифрования нам необходимо предварительно обработать введёный ключ и извлечь из него ikey. Это можно сделать поксорив первую половину ключа со второй. И с помощью ikey уже шифровать или расшифровывать сообщение.</p>
<p>Реализацию ксора в python нашёл на просторах инета (выглядит довольно красиво, я пока так не умею :-)), остальное писал сам. Вот исходник:</p>
<div class="codesnip-container" >
<div class="python codesnip" style="font-family:monospace;"><span class="co1">#!/usr/bin/env python</span><br />
<span class="co1"># -*- coding: utf-8 -*-</span></p>
<p><span class="kw1">import</span> <span class="kw3">random</span>, <span class="kw3">itertools</span>, <span class="kw3">struct</span></p>
<p><span class="kw1">def</span> generate_strings<span class="br0">&#40;</span>ikey, q=10<span class="br0">&#41;</span>:<br />
keys = <span class="br0">&#123;</span><span class="br0">&#125;</span><br />
<span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span>q<span class="br0">&#41;</span>:<br />
<span class="co1">#print &quot;%d.&quot; % i,</span><br />
keys<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = <span class="st0">&quot;&quot;</span><br />
<span class="kw1">for</span> j <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span><span class="kw2">len</span><span class="br0">&#40;</span>ikey<span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
<span class="co1">#keys[i] += hex(random.randint(0, 15))[2 : ]</span><br />
keys<span class="br0">&#91;</span>i<span class="br0">&#93;</span> += <span class="kw2">chr</span><span class="br0">&#40;</span><span class="kw3">random</span>.<span class="me1">randint</span><span class="br0">&#40;</span><span class="nu0">0</span>, <span class="nu0">255</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="co1">#print keys[i]</span><br />
<span class="kw1">return</span> keys</p>
<p><span class="kw1">def</span> xor <span class="br0">&#40;</span>s, key<span class="br0">&#41;</span>:<br />
key = <span class="kw3">itertools</span>.<span class="me1">cycle</span><span class="br0">&#40;</span>key<span class="br0">&#41;</span><br />
<span class="kw1">return</span> <span class="st0">&#187;</span>.<span class="me1">join</span><span class="br0">&#40;</span><span class="kw2">chr</span><span class="br0">&#40;</span><span class="kw2">ord</span><span class="br0">&#40;</span>x<span class="br0">&#41;</span> ^ <span class="kw2">ord</span><span class="br0">&#40;</span>y<span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="kw1">for</span> <span class="br0">&#40;</span>x,y<span class="br0">&#41;</span> <span class="kw1">in</span> <span class="kw3">itertools</span>.<span class="me1">izip</span><span class="br0">&#40;</span>s, key<span class="br0">&#41;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">def</span> generate_keys<span class="br0">&#40;</span>ikey<span class="br0">&#41;</span>:<br />
keys = generate_strings<span class="br0">&#40;</span>ikey<span class="br0">&#41;</span><br />
<span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span><span class="kw2">len</span><span class="br0">&#40;</span>keys<span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
keys<span class="br0">&#91;</span>i<span class="br0">&#93;</span> = xor<span class="br0">&#40;</span>keys<span class="br0">&#91;</span>i<span class="br0">&#93;</span>, ikey<span class="br0">&#41;</span> + keys<span class="br0">&#91;</span>i<span class="br0">&#93;</span> <span class="co1">#xor(keys[i], b) + b</span><br />
<span class="kw1">return</span> keys</p>
<p><span class="kw1">def</span> bs2s<span class="br0">&#40;</span>bs<span class="br0">&#41;</span>:<br />
ss = <span class="st0">&quot;&quot;</span><br />
<span class="kw1">for</span> i <span class="kw1">in</span> bs:<br />
s = <span class="kw2">hex</span><span class="br0">&#40;</span><span class="kw2">ord</span><span class="br0">&#40;</span>i<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#91;</span>2 : <span class="br0">&#93;</span><br />
<span class="kw1">if</span> <span class="kw2">len</span><span class="br0">&#40;</span>s<span class="br0">&#41;</span> == <span class="nu0">1</span>:<br />
ss += <span class="st0">&quot;0&quot;</span><br />
ss += s<br />
<span class="kw1">return</span> ss</p>
<p><span class="kw1">def</span> s2bs<span class="br0">&#40;</span>ss<span class="br0">&#41;</span>:<br />
bs = <span class="st0">&quot;&quot;</span><br />
<span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span>0, <span class="kw2">len</span><span class="br0">&#40;</span>ss<span class="br0">&#41;</span>, 2<span class="br0">&#41;</span>:<br />
bs += <span class="kw2">chr</span><span class="br0">&#40;</span><span class="kw2">int</span><span class="br0">&#40;</span>ss<span class="br0">&#91;</span>i : i +2<span class="br0">&#93;</span>, 16<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="kw1">return</span> bs</p>
<p><span class="kw1">def</span> restore_key<span class="br0">&#40;</span>key<span class="br0">&#41;</span>:<br />
c = <span class="kw2">len</span><span class="br0">&#40;</span>key<span class="br0">&#41;</span> / 2<br />
<span class="kw1">return</span> xor<span class="br0">&#40;</span>key<span class="br0">&#91;</span> : c<span class="br0">&#93;</span>, key<span class="br0">&#91;</span>c : <span class="br0">&#93;</span><span class="br0">&#41;</span></p>
<p><span class="kw1">if</span> __name__ == <span class="st0">&quot;__main__&quot;</span>:<br />
action = <span class="st0">&quot;&quot;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;Select action:<span class="es0">\n</span>g &#8212; generate keys<span class="es0">\n</span>c &#8212; encrypt or decrypt file<span class="es0">\n</span>q &#8212; quit&quot;</span><br />
<span class="kw1">while</span> action <span class="sy0">!</span>= <span class="st0">&quot;q&quot;</span>:<br />
action = <span class="kw2">raw_input</span><span class="br0">&#40;</span><span class="st0">&quot;&amp;gt; &quot;</span><span class="br0">&#41;</span><br />
<span class="kw1">if</span> action == <span class="st0">&quot;g&quot;</span>:<br />
ikey = <span class="kw2">raw_input</span><span class="br0">&#40;</span><span class="st0">&quot;Enter initial key value: &quot;</span><span class="br0">&#41;</span><br />
keys = generate_keys<span class="br0">&#40;</span>ikey<span class="br0">&#41;</span><br />
<span class="kw1">print</span> <span class="st0">&quot;Generated keys:&quot;</span><br />
<span class="kw1">for</span> i <span class="kw1">in</span> <span class="kw2">range</span><span class="br0">&#40;</span><span class="kw2">len</span><span class="br0">&#40;</span>keys<span class="br0">&#41;</span><span class="br0">&#41;</span>:<br />
<span class="kw1">print</span> <span class="st0">&quot;%d. %s&quot;</span> <span class="sy0">%</span> <span class="br0">&#40;</span>i, bs2s<span class="br0">&#40;</span>keys<span class="br0">&#91;</span>i<span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
<span class="kw1">elif</span> action == <span class="st0">&quot;c&quot;</span>:<br />
f_in_name = <span class="kw2">raw_input</span><span class="br0">&#40;</span><span class="st0">&quot;Enter input file name: &quot;</span><span class="br0">&#41;</span><br />
f_out_name = <span class="kw2">raw_input</span><span class="br0">&#40;</span><span class="st0">&quot;Enter output file name: &quot;</span><span class="br0">&#41;</span><br />
key = <span class="kw2">raw_input</span><span class="br0">&#40;</span><span class="st0">&quot;Enter key: &quot;</span><span class="br0">&#41;</span><br />
<span class="kw1">try</span>:<br />
key = restore_key<span class="br0">&#40;</span>s2bs<span class="br0">&#40;</span>key<span class="br0">&#41;</span><span class="br0">&#41;</span><br />
f = <span class="kw2">open</span><span class="br0">&#40;</span>f_in_name, <span class="st0">&quot;rb&quot;</span><span class="br0">&#41;</span><br />
c = xor<span class="br0">&#40;</span>f.<span class="me1">read</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, key<span class="br0">&#41;</span><br />
f.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
f = <span class="kw2">open</span><span class="br0">&#40;</span>f_out_name, <span class="st0">&quot;wb&quot;</span><span class="br0">&#41;</span><br />
f.<span class="me1">write</span><span class="br0">&#40;</span>c<span class="br0">&#41;</span><br />
f.<span class="me1">close</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="kw1">except</span>:<br />
<span class="kw1">print</span> <span class="st0">&quot;Errors :-(.&quot;</span><br />
<span class="kw1">elif</span> action <span class="sy0">!</span>= <span class="st0">&quot;q&quot;</span>:<br />
<span class="kw1">print</span> <span class="st0">&quot;Invalid action.&quot;</span></div>
</div>
<p>Единственная поправка к алгоритму, который я описал &#8212; ключи перед выводом я перевожу в шестнадцатиричное число, чтобы не хранить ключи в бинарном виде, ну и после ввода так же перевожу обратно. На этом всё.</p>
<p>Ссылки к статье:<br />
<a href="http://code.activestate.com/recipes/496970/">http://code.activestate.com/recipes/496970/</a> &#8212; &#171;Recipe 496970: xor for strings&#187;.</p>
]]></content:encoded>
			<wfw:commentRss>http://zetblog.ru/programming/200905/python-%d0%b3%d0%b5%d0%bd%d0%b5%d1%80%d0%b0%d1%86%d0%b8%d1%8f-%d0%b3%d1%80%d1%83%d0%bf%d0%bf%d1%8b-%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%b9/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

