Избранное

Находки с Волкова

Керамика, запонка, гильза, резиновая пробка и несколько неопознанных находок, монета только одна — 1 копейка 1976 года

Во дворе того же дома на Волкова, где мне показали два дореволюционных клейма на кирпиче, прошёлся сегодня с металлодетектором. Спасибо хозяевам — А. и О., а так же М. за гостеприимство!

Искать было непросто — во дворе, как это обычно и бывает, очень много бытового металла — гвоздей, пробок от спиртного, фольги, но всё же упорство было вознаграждено. Из более-менее интересных находок — овальная запонка с рисунком и мосиновская гильза 1916 года компании United States Cartridge Company (Лоуэлл, Массачусет, США).

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

Овальная находка, предположительно — запонка, на обратной стороне видна обломанная ножка

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

Одну из находок оставил хозяевам — в мощённой тропике нашёлся железнодорожный костыль. Вышел довольно легко, видимо был просто забит в землю. С какой такой стати — ещё одна загадка.

3 июня   сокровища

Элиуд Кипчоге

Это Элиуд Кипчоге и он смотрит на ваши казуальные забеги в модных «Найки», как на говно

Я бегал ещё до того, как это было модно — когда готовились к спуску в пещеры Караби-яйла, мы пробегали 10 километров два раза в неделю по московским Воробьёвым горам. Цель тогда была — «выбежать из часа», то есть пробежать десятку по пересечёнке меньше, чем за час.

Я не являюсь хорошим бегуном, да и комплекция у меня не беговая, для меня бегать — трудно. Я никогда не пытался осилить марафон (42 километра, напоминаю), уверен, что пробегу его, если буду тренироваться. Но я никогда не считал это плёвым делом.

Каждый раз, когда я слышу, что кто-то из моих знакомых пробежал марафон, я искренне считаю, что это круто, а когда я прочитал, что кениец Элиуд Кипчоге пробежал марафон за два часа и двадцать пять секунд, я был просто поражён.

Это почти в два раза быстрее меня на всей дистанции! Со средней скоростью выше, чем я обычно езжу по городу на велике!

Я вспомнил себя, бегущего эти чёртовы бесконечные десять километров, уговаривающий свои мышцы потерпеть и вот я каким-то чудом бегу в два раза быстрее и не снижаю скорости! Исключено, невозможно, невыполнимо!

Чёрт возьми, такие достижения я уважаю!

28 апреля  

Баг

Принято считать, что слово «баг» появилось 9 сентября 1946 года, когда Грейс Хоппер, которая работала в тот момент в Гарвардском университете с ЭВМ «Марк II», проследила ошибку в работе программы до реле машины, куда попал мотылёк. Грейс вклеила насекомое в технический журнал, сопроводив шуткой «Первый реальный случай обнаружения жучка» («First actual case of bug being found»).

На самом деле это одна из версий проникновения термина в среду компьютерщиков. В выпущенном в 1892 году «Стандартизованном словаре электротехники» можно прочитать:

Баг — это любая неисправность или дефект в электрических соединениях или работе электрических аппаратов

Как видим слово появилось раньше 1946 и даже не в 20 веке. По одной из версий термин придумал и популяризировал Томас Эдисон — известный американский предприниматель, Стив Джобс своего времени.

В своих письмах и дневниковых заметках он нередко употребляет это слово. Выше — скан его письма от 3 марта 1878 года (оригинал можно купить за пару тысяч долларов). В пятой строчке, сразу после артикля, написано «bug».

Употреблял ли Эдисон это слово в знакомом нам значении? Да! Так 18 ноября 1878 года он написал Тивадару Пушкашу (венгерскому учёному, физику, и изобретателю первой в мире телефонной станции):

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

Так что термину в этом году исполняется по меньше мере 140 лет.

Казанская страховая доска

Страховые доски — металлические таблички, которые до революции крепились на фасад застрахованного строения (или над дверью застрахованной квартиры). Они всё ещё попадаются на старинных зданиях в российских городах, но всё реже — за ними охотятся коллекционеры.

Предпоследняя, довольно известная в Казани страховая доска висела на улице Волкова, но в прошлом году я заметил, что её нет на прежнем месте — говорят выкупил у хозяев известный в Казани коллекционер. Большинство сохранившихся досок сейчас в плачевном состоянии — без краски, ржавые, но когда-то они были очень красивы.

Узнать местоположение последней страховой доски оказалось непросто, возможно поэтому коллекционеры пока до неё не добрались. Даже зная примерный адрес, нашёл только через полчаса поисков. Доска маленькая, сильно заржавела, пришлось занимать объектив у приятеля, чтобы снять.

Написано там следующее: «въ обществѣ РОССІЯ застраховано». На фоне — почти уже незаметная восьмиугольная звезда, намёк на икону «Неопалимая Купина». «Неопалимая Купина» почитается как заступница при пожарах, так что такая страховая доска одновременно играла ещё и роль оберега.

ProxyJump

Как-то писал заметку про .ssh/config и опцию ProxyCommand, а потом почти сразу после этого, перечитывая руководство по теме, наткнулся на схожую опцию ProxyJump:

Host 10.1.10.*
        IdentityFile ~/.ssh/id_rsa
        #ProxyCommand /usr/bin/ssh -W %h:%p bolk@rptn.tunnel
        ProxyJump rptn.tunnel

Возможности её у́же, зато пользоваться ею проще. Кроме указания в конфиге, её просто использовать и из командной строки, как ключ, причём цепочки выстраиваются очень просто:

ssh -J bolk.sed-php7:2258,rptn.tunnel 10.1.10.158

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

🍎 + 🍍 + 🍌 = 🥗

Уравнение (118.71КиБ)
Казалось бы, обычная картинка, которых сотни — реши фрукты

По интернету ходят сотни картинок, где надо «решить фрукты» — в уравнение в качестве имён переменных подставлены какие-нибудь посторонние предметы. В вариантах чуть посложнее надо быть повнимательнее — например, в уравнениях везде бананы, а в одном месте гроздь из трёх.

Когда я увидел картинку выше, ради развлечения сунул её в «Вольфрам» — хотелось посмотреть как ему указать, что числа должны быть целые. Заинтересовало, что решения не нашлось. Я задумался и внимательно посмотрел на фрукты, в них подвоха тоже не увидел.

Оказалось, что картинка выше — пранк по мотивам статьи на «Кьюоре». Решить уравнение, которое на ней, сможет лишь небольшое количество людей со специальными знаниями, а прямой перебор значений займёт совершенно нереальное время.

Минимальные подходящие числа для уравнения такие (ответ проверял на ЯП «Эр»):

`🍎` <- 154476802108746166441951315019919837485664325669565431700026634898253202035277999
`🍌` <- 36875131794129999827197811565225474825492979968971970996283137471637224634055579
`🍍` <- 4373612677928697257861252602371390152816537558161613618621437993378423467772036

print(`🍎` / (`🍌` + `🍍`) + `🍌` / (`🍎` + `🍍`) + `🍍`/(`🍎` + `🍌`)) # [1] 4

Это числа от 79 знаков и больше! Где уж такое решить!

2018  

Ассемблер под Линукс

Заметка про полноту по Тьюрингу команды присваивания в ассемблере натолкнула меня на мысль, что я как-то не удосужился попрограммировать на ассемблере под Линукс — эту ОС я начал осваивать примерно в то же время, когда начал быстро терять интерес к ассемблеру.

Тогда не довелось, решил вчера попробовать. Теорию в очень общих чертах я знал — есть системные вызовы (сисколы), которые можно дёргать какой-то командой, имена сисколов мне знакомы через Си. Попробовал написать программу, которая выводит на вход то, что ей дают на вход. Быстро разобрался, что регистры сейчас имеют впереди букву «эр», а сисколы делаются прерыванием №128. Удобный способ, параметры идут в логичном виде — последовательно через регистры в почти алфавитном порядке (ближе к концу последовательность нарушается):

MOV RAX, 3 ; sys_read
MOV RBX, 0 ; stdin
MOV RCX, string ; адрес строки, которую выведем на экран
MOV RDX, len ; длина строки
INT 0x80

Но я где-то читал, что для сисколов есть команда новее — syscall, просто заменил вызов прерывания на эту команду — не заработало. Полез в интернет. Оказалось, у там другой набор параметров, да и сами сисколы имеют другие номера.

MOV RAX, 0 ; sys_read
MOV RDI, 0 ; stdin
MOV RSI, string ; адрес строки, которую выведем на экран
MOV RDX, len ; длина строки
SYSCALL

К тому времени меня посетила мысль сделать простенький аналог линуксовой утилитки tee, но для этого нужно было как-то прочитать параметры командной строки. Гугление показало, что после запуска программы на стеке лежат количество параметров и указатели на каждый из них, причём каждый параметр кончается нулём — обычная сишная строка.

Так как системный вызов для открытия файла (sys_open) как раз требует на вход сишную строку, я передал указатель, который взял со стека, в сискол, ожидая, что всё заработает. Это было моей ошибкой. Я потратил не меньше часа, разбираясь, что я сделал не так, перебирал способы передачи параметров, ползал по стеку при помощи отладчика gdb, ничего не помогало, пока не забрезжила догадка, что сами параметры командной строки тоже лежат на стеке и системному вызову это может не нравится.

Попробовал скопировать строку оттуда в данные и всё заработало. Не знаю что это было, пока не гуглил, возможно сделано из соображений безопасности. Времени потерял изрядно.

Пока получилась очень простая утилитка, но хочу её дописать как выпадет свободный вечер — сделать поддержку указания нескольких файлов и флага для режима присоединения. Размер радует, кстати, — всего 752 байта.

Дизассемблируй это

Дум (71.16КиБ)
«ДУМ», скомпилированный с использованием одних только команд MOV

В моей жизни последовательно сменяли друг друга три ассемблера. Первый, для компьютера «Радио-86РК», я выучил по комментариям к ассемблерному коду в журнале «Радио» — другой литературы не было, а до моего знакомства с интернетом оставалось несколько лет. Потом были последовательно ассемблеры для «Спектрума» и интеловских процессоров.

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

В ассемблере есть такая команда — MOV (в некоторых ассемблерах — LD), записывает содержимое одного аргумента в другой. Сейчас набор комманд разросся, аргументом может быть почти что угодно — регистр, ячейка в памяти, сумма некоторого числа, одного регистра и другого, умноженного на число, но по сути это всегда присваивание.

И вот оказалось, что эта команда — полная по Тьюрингу. Звучит невероятно, но это так. Некие ребята заморочились и сделали компилятор, который компилирует любую программу на Си в последовательность команд MOV. Причём им даже ДУМ удалось скомпилировать, правда один кадр рисуется семь часов. Кстати, такая программа неуязвима для горюшка века — Мелтдауна и Спектра.

Есть небольшая (на 156 страниц и 90% воды) презентация, достаточно популярно объясняющая как этого удалось достичь, но для её чтения надо знать ассемблер, поэтому я позволю себе раскрыть детали трансляции двух инструкций, чтобы пояснить принцип для тех, кто ассемблера не знает или ленится причитать.

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

mov [X], 0
mov [Y], 1
mov R, [X]

У нас есть два числа в аргументах «X» и «Y», результат сравнения которых попадает в «R» — там будет ноль, если числа не равны и единица в противном случае. Как же это работает?

Первой командой ноль записывается в ячейку по адресу «X». Это ассемблер, у нас тут всё — число, остальное — человеческие интерператации, поэтому записанное в «X» мы используем как адрес. Второй командой единица записывается в ячейку по адресу «Y». Третьей командой мы читаем значение по адресу «X» и если значения в «X» и «Y» совпадают, то ноль перетрётся единицей (и она попадёт в R), если нет, то в ячейке по адресу «X» ноль останется (который попадёт в R).

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

Возьмём, например, логическое «ИЛИ» («OR»), тут чуточку сложнее:

OR_ADDRS: dd OR_0, OR_1
OR_0: dd 0, 1
OR_1: dd 1, 1
; …
mov eax, X
mov edx, [OR_ADDRS + eax]
mov eax, Y
mov eax, [eax + edx]
mov R, eax

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

Что тут происходит? В регистр (переменную, с которыми работает процессор) «eax» записывается значение «X» (возможные входные значения у нас тут — ноль или единица, численное представление булевых значений).

Далее в регистр «edx» записывается число из адреса, который является суммой адреса массива OR_ADDRS и содержимого регистра eax. Таким образом в eax попадёт OR_0 или OR_1, в зависимости от того былы записаны в eax ноль или единица. Эти значения — тоже числа и являются адресами двух других массивов из двух элементов.

Далее в eax мы записываем аргумент Y, его значение складывается с адресом полученным на предыдущем шаге и из получившегося адреса мы читаем записанное там значение. В переводе на ПХП получается следующее:

function mov_or(int $X, int $Y): int
{
    define('OR_0', [0, 1]);
    define('OR_1', [1, 1]);

    define('OR_ADDRS', [OR_0, OR_1]);

    $R = OR_ADDRS[$X][$Y];

    return $R;
}

Кстати, интересно, что у знаменитого дисассемблера «ИДА» от полученной таким образом программы крепко уносит крышу — при попытке отладки диссасемблер не видит никаких ветвлений и падает на анализе кода. Получился бы неплохой метод защиты от анализа, если бы не производительность.

Интернет-археология: браузер ViolaWWW

Неудачная попытка запуска (12.62КиБ)
Моя попытка запустить браузер под Линукс пока завершилась провалом

Пока читал про «Си-минус-минус», наткнулся на браузер ViolaWWW. Браузер разрабатывался с 1991 года в университете Беркли одним-единственным человеком — Вэй Пей-Юанем.

Эта вещь достойна внимания из-за примечательного факта — там реализованы таблицы стилей, за несколько лет до появления CSS, а так же первый скриптовый язык — задолго до «ДжаваСкрипта» и «Си-минус-минуса»! Причём с событиями и подобием аякса!

Автор написал несколько программ на своём языке, например — шахматы. Я пока не нашёл документацию, зато обнаружил несколько примеров. Например, скрипт выводящий синусоиду:

\class {field}
\name {wave}
\parent {}
\children {wave.sb}
\script {
    switch (arg[0]) {
    case "graph":
        f = float(arg[1]);
        xx = width();
        r  = height() / 2.0;
        theta = 0;
        for (x = 20; x < xx; x += 2) {
            theta = theta + 0.1;
            y = sin(theta * f) * r + r;
            drawLine(x, y, x, y + 1);
        }
        return;
    break;
    }
    usual();
}
\width {300}
\height {200}
\
\class {slider}
\name {wave.sb}
\parent {wave}
\script {
    switch (arg[0]) {
    case "_shownPositionV":
        usual();
        send(parent(), "graph", arg[1]);
        return;
    break;
    }
    usual();
}
\x {2}
\y {2}
\width {15}
\height {200}
\shownSizeV {10}

К сожалению, позапускать программы пока нечем. Исходный код я нашёл, но под Линуксом он компилироваться не захотел, собственно, судя по коду, он никогда под ним и не собирался. Я сделал минимально необходимые правки, код собрался, но попытка запуска завершилась крахом. Подумаю стоит ли тратить силы дальше.

Даже интересно какой бы веб мы увидели сейчас, если бы этот браузер тогда получил дальнейшее распространение! Получается в 90-х он умел больше, чем некоторые браузеры в двухтысячных. Например в скриптовом языке я заметил селекторы nthChild и даже nthWord!

Насколько я могу видеть, поддерживалось более десятка форматов графики, в том числе всем знакомый GIF, правда без анимации и в формате 1987 года, а так же сейчас уже экзотический XBM (до относительно недавнего времени поддерживался «Эксплорером», «Сафари» и «Оперой»).

Ранее Ctrl + ↓