• Fucky new year!

      Простите за мат в заголовке, это намёк на развлечение, начало которому дал язык «Брейнфак» — написать на каком-либо языке код, выполняющий что-то разумное, не используя букв и цифр. Мы уже видели JSFuck, PHPFuck, теперь я вам хочу представить Bashfuck:

      __=${_##*/};____=<(:);___=${__#???};_____=$((${#___}<<${#___}))
      __=${__::-${#___}}${____:$_____:${#___}}
      __=$__$((${#__}|$_____))$((${#__}));___=$___${__:${#___}:${#___}};____=$($__<<<$_____|$__)
      _____=${____:$((${#__}-${#___})):${#?}};___=$___$_____$_____;____=$($__<<<$____|$__|$__)
      ___=$___${____:$((${#?}+${#__})):${#?}};___=$___' '${____:$((${#___}+${#___})):${#?}}
      ___=$___${__:$((${#____}/${#___}-${#?})):${#?}};___=$___${____:$((${#____}#$_____-${#___})):${#?}}
      ___=$___\ ${____:$((${#__}+${#?})):${#?}}${__:$((${#__}>>${#?})):${#?}}${__:${#_____}:${#?}}
      ___=$___${____:$((${#___}-${#?}-${#?})):${#?}};___=${___,,}
      ____=${____:$((${#___}+${#__}-${#?})):$((${#?}+${#?}))}
      ____=${____::${#?}}${__:${#_____}:${#?}}${____:${#?}};${____,,}<<<${___^}

      Для запуска потребуется «Баш» четвёртой версии. Ничего вредоносного скрипт не делает смело запускайте из-под «рута», просто выведет надпись «Happy new year». Исходник надо скопировать в файл и запустить.
      Как оно работает?
    • Шахматы на чистом sed

        В Линуксе и многих других системах существует утилита командной строки sed («сед») — это несложный редактор, которые преобразует текст, попадающий ему на вход при помощи несложных команд.

        Его, в основном, используют для всяких мелких нужд в bash-скриптах — заменить одну строку на другую, что-то удалить и так далее. Если говорить терминами более привычных языков, в «седе» доступны две строковые переменные, в одной из которых можно что-нибудь проверять, заменять, а со второй только обмениваться данными из первой, метки, команды переходов на метки и группировка команд, плюс ещё несколько менее полезных директив.

        Вот на этом безобразии я решился написать шахматы, причём такие, чтобы можно было бы играть с компьютером.
        Читать дальше →
      • Bash: автообнаружение противника для сетевой игры на «Маках»

          Время от времени мне нравится писать на bash какие-нибудь не слишком тривиальные вещи. Вроде сетевых шахмат, о которых я уже рассказывал на «Хабре».

          Недавно я мысленно вернулся к ним и подумал как было бы круто, если игра сама находила бы партнёра для игры в сети. Т.е. будучи запущенной, игрушка должна как-то поискать в сети тех, кто готов к поединку.

          Сканировать вообще все адреса невозможно долго. Есть два некрасивых решения «в лоб» — просканировать текущую подсеть или посмотреть в таблицу ARP, подсоединиться к тем, кто там есть. Но, во-первых, такой перебор всё равно будет медленным, а во-вторых, не найдёт всех потенциальных соперников (соперники могут быть в других подсетях, а в таблице ARP вообще далеко не все участники сети).

          Вообще, подобная проблема давным-давно решена в операционках — например, когда я настраивал дома сетевой принтер, операционная система нашла его сама, я не указывал IP или что-то ещё. В «Маках» для этого есть технология «Бонжур» (реализация «Зероконфа»).

          Нельзя ли использовать эту технологию в «Баше»?
          Можно!
        • Поддержка камеры и распознавание цифр в браузере «Опера»

            Я вчера заморочился на отличненько. Мне показалось скучным и грустным вводить цифры счёта за квартиру в окошко «Госуслуг» и решил сделать автоматическую распознавалку чисел, попутно изучив работу с камерой из браузера.
            Читать дальше →
          • Первый язык программирования высокого уровня — Планкалкюль

              Планкалкюль (Plankalkül) — первый в мире язык программирования высокого уровня, разработанный немецким инженером Конрадом Цузе между
              1942 и 1946 годами для его компьютера «Z4» (компьютер на снимке ниже, фото взято из «Википедии»).

              Z4

              Шла Вторая Мировая Война, Цузе работал в отрыве от учёных других стран, совершенно самостоятельно. За это время он создал не только язык программирования,
              но и написал на нём 49 страниц программ для оценки шахматных позиций. Полностью его работа была опубликована много позже, в 1972.

              Рискну рассказать об этом языке программирования, в качестве археологического изыскания. Тем более, что на русском языке об этом языке сказано очень мало.
              Читать дальше →
            • Сетевая игра на bash: шахматы

                Я давно хотел написать какую-нибудь сетевую игру на bash, причём желательно, чтобы управление было удобное, с клавиатуры, обычными курсорным клавишами. Вообще, тема интерактивного взаимодействия в bash глубже, чем «введите число, нажмите „Enter“» не раскопана. Мне пришлось всё изобретать и исследовать самостоятельно. Я очень старался найти что-то похожее по уровню интерактивности, но не нашёл.

                Поскольку тонкости управления с клавиатурой съели очень много моего времени, я не стал заморачиваться с тонкостями совместимости, поэтому игра тестировалась только под Mac OS X, есть ненулевая вероятность, что она заработает и под Linux и уж точно её можно допилить там до рабочего состояния.

                Для работы игра требует наличия nc (aka Netcat) и терминала с поддержкой 256 цветов (под Mac OS рекомендую iTerm2). При наличие интереса к игре, допилю до терминала на 16 цветов и /dev/tcp. Кстати начал выкладывать все свои шел-поделки на ГитХаб.

                Сетевые шахматы на Bash


                Так как игра сетевая, у неё требуется указать два параметра, о которых она расскажет, если её запустить без них. Первый — адрес машины противника, второй — порт. Порт выбирается одинаковым на обеих машинах. Игру можно запустить и на одной машине, в двух консолях (на скриншоте как раз такой случай).

                Играть просто — в каждый момент времени активна только одна доска (на скриншоте — правая, у неё буквы и цифры вокруг доски ярче), на активной доске курсор двигается курсорными клавишами — ←, →, ↑ и ↓, взять фигуру и поставить её на доску — по клавише пробела или Enter. Как только вы поставили фигуру на доску, ход переходит к сопернику. «Съесть» фигуру соперника проще простого — достаточно поставить свою фигуру на чужую. В игре есть защита — нельзя «съесть» свою фигуру.

                Ничего помимо этого в игре нет — не производится правильность контроля ходов, нет проверки на завершение игры, можно даже ходить фигурами соперника. Было очень сложно придумать как обрабатывать нажатия в shell, так что остальное сделать я просто не успел, не поместилось в формат «игрушка за вечер».

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

                Читать дальше →
              • Воздушный бой на чистом HTML

                  Я долго колебался куда отнести этот пост, решил, что в «ненормальном программировании» ему самое место.
                  Воздушный бой

                  Все в последнее время настолько в восторге от новых возможностей браузеров, что пишут игру за игрой на HTML5/CSS/JavaScript. Это всё скучно. Вчера перед сном я размышлял об игре на чистом HTML (даже без CSS), а сегодня, пока собирался в Самару, на 404fest, потихоньку её написал.

                  Встречайте — Pure HTML Air Fight. Написано на чистом HTML, без использования JavaScript, CSS и серверной логики. На сервере отрабатывает только скрипт, контролирующий введённый URL и запускающий игру, если URL ошибочен.

                  Задача классическая — попасть в пролетающий самолёт, внизу есть кнопка, запускающая ракету. Скорость самолёта и задержка меняется (на самом деле они жёстко зависят от момента пуска ракеты, у меня же чистый HTML, никакого рандома).

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

                  P.S. кажется, из-за хабраэффекта у меня ложится сервер.
                • Opera 10.50 и CSS-хаки

                    Opera 10.50 стала поддерживать border-radius и много других интересных вещей, в этой связи встал вопрос — как отличить Opera 10.50 от более ранних версий в CSS?

                    Например, у меня на сайте скруглённые уголки для «Оперы», начиная с версии 9.50 делаются при помощи SVG, 10.50 вполне могла бы нарисовать их без этого «изыска». Помучался-помучался и придумал несколько CSS-хаков, собственного изобретения.
                    Читать дальше →
                  • Загрузка браузером нескольких файлов

                      Если нужно дать пользователю возможность загрузки нескольких файлов, традиционное решение на данный момент — использовать для этой цели Flash (реже — Java applet или ActiveX). В случае, если соответствующий плагин недоступен, пользователю, как правило, показывают стандартный HTML-элемент для загрузки файла.

                      Последнюю ситуацию можно улучшить, если использовать встроенную в браузеры возможность множественной загрузки файлов. Из всех браузеров сейчас данную возможность не поддерживает только Internet Explorer (впрочем, мы ещё не видели девятую версию, может там что-то изменится), остальные браузеры — Opera 9 и выше (а так же версии 3.5—6.05), Firefox 3.6+, Chrome 3.0.191.0+ и Safari 4.0.1+ такую возможность предоставляют.

                      Достаточно написать что-то вроде
                      Copy Source | Copy HTML
                      1. <form enctype="multipart/form-data" method="post">
                      2.    <input type="file" min="1" max="9999" name="file[]" multiple="true" />
                      3.    <input type="submit" name="submit" />
                      4. </form>
                      PHP оказался готов к такой конструкции (именно для него в параметре «name» стоят квадратные скобки), он просто разложит загружаемые файлы по элементам массива $_FILES, если только мы не используем «Оперу».

                      К сожалению, «Опера» (ещё с версии 3.5) отправляет, при использовании мультизагрузки, файлы в контейнере «multipart/mixed», который PHP не понимает.

                      Я попробовал исправить эту ситуацию.
                      Читать дальше →
                    • data URI

                        Пару лет назад я занимался проблемой data URL в Internet Explorer, добился определённых результатов, но то, что получилось, использовать было невозможно. Data URL (иногда его ещё называют «протокол data:») — возможность вставлять ресурсы (графику, CSS, JavaScript и так далее) в HTML код.


                        Подробнее о data URL можно узнать из свежей статьи на «Хабре» «Картинки в теле страницы с помощью data:URL». Хотелось только её дополнить двумя замечаниями: IE8b1 поддерживает data URL длиной не более 32Кб, в современных версиях других браузеров ограничений увидеть не удалось, Safari/Opera/FF показали изображения размером около 700Кб.


                        Теперь амбула.


                        Вчера ночью мне пришла в голову идея как можно попытаться корректно совместить data URL и включение картинок через протокол mhtml. То, что у меня не получилось два года назад, получилось сейчас.


                        Результат — готовый код на PHP из двух функций. Первую функцию («bolk_data_uri_header») нужно вызвать в самом начале перед выводом любого вашего кода, вторую («bolk_data_uri») собственно для включения картинки в код.


                        Надеюсь на примерах всё понятно:
                        bolk_data_uri_header();
                        bolk_data_uri('myjpeg.jpg');
                        bolk_data_uri('ourpng.png', 'border: 2px dotted red');
                        


                        Код самой библиотеки:
                        function bolk_data_uri_header() 
                        { 
                            echo "<!--\n" 
                                ."Content-Type: multipart/related; boundary=\"=_NextPart_01C6A9B1.539AB070\"\n\n" 
                                ."--=_NextPart_01C6A9B1.539AB070\n" 
                                ."Content-Transfer-Encoding: base64\n" 
                                ."Content-Type: text/html\n" 
                                ."-->\n\n"; 
                        
                        } 
                        
                        function bolk_data_uri($file, $style = '') 
                        { 
                            if (!( file_exists($file) && ($data = @getimagesize($file)) )) return false; 
                        
                            $name = uniqid('', true); 
                        
                            if ($style <> '') $style = ' style="'.htmlspecialchars($style).'"'; 
                            $mime = strpos($_SERVER['HTTP_USER_AGENT'], 'Gecko') ? " type='{$data['mime']}" : '';
                        
                            echo "<!--\n" 
                                ."--=_NextPart_01C6A9B1.539AB070\n" 
                                ."Content-Location: {$name}\n" 
                                ."Content-Transfer-Encoding: base64\n" 
                                ."Content-Type: {$data['mime']}; -->\n" 
                                ."<object data='data:{$data['mime']};base64,\n\n"; 
                        
                            echo base64_encode(file_get_contents($file)); 
                        
                            echo "' {$data[3]}{$style}{$mime}'><img " 
                                ."src='mhtml:http://{$_SERVER['HTTP_HOST']}"
                                ."{$_SERVER['REQUEST_URI']}!{$name}' {$data[3]}{$style} /></object>\n\n" 
                                ."<!--\n" 
                                ."--=_NextPart_01C6A9B1.539AB070-->"; 
                        
                            return true; 
                        }
                        



                        Секрет в совмещении данных, чтобы IE, обратившись к странице по протоколу mhtml нашёл нужный кусор, «спрятанный» внутри тега, а остальные браузеры увидели бы картинку через data URL.


                        Код тестировался под Opera 9.50b, FF 2.0.0.13, Safari 3.1 и IE6. Предложения и результаты испытаний — прошу в комментарии.


                        Оригинал записи опубликован в моём блоге.