Попался мне недавно на глаза вот этот разворот из детской книжки «Энциклопедия профессора Фортрана» 1991-го года. На ней, как мы видим, высоколобый Новосельцев с указкой говорит, что справа закодирована фраза «ПРОЧИТАЙ ГЛАВУ "ЯЗЫКИ ПРОГРАММИРОВАНИЯ"».
Сразу бросается в глаза, что бинарные строки справа не восьмибитные, как мы все привыкли, а на бит короче. Ещё, при внимательном рассмотрении, в закодированных числах узнаются пробелы, у них код 32 или 0100000. Только первый почему-то на одиннадцатой позиции, а не на девятой, как в фразе на русском.
Всё это меня очень заинтересовало, я отложил себе эту картинку, а сегодня, по пути домой, разобрался в этих странностях.
Воспользовавшись программой для распознавания, я перевёл текст на картинке в буквы и цифры, вырезал оттуда закодированное и попробовал перегнать этот кусок в буквы. Получилась следующая строка: pro~itajte glawu "qzyki programmirowaniq".
Какой-то странный транслит, но что написано догадаться можно. Заодно стало понятно почему позиции пробела не совпадают — на самом деле закодировано не «прочитай», а «прочитайте».
Теперь осталось понять что это за кодировка. Не уверен, что я когда-либо в жизни сталкивался с КОИ-7, но название такое слышал. Предположил, что это она и не ошибся.
Латинские символы видно, потому что эта кодировка содержит в себе несколько наборов символов, которые надо переключать специальным кодом. Русские символы находятся в тех же позициях, что и латинские, а поскольку кодировка ЮТФ-8, который мы все пользуемся, совместима с латинским набором КОИ-7, мы видим не бинарный мусор, а какие-то буквы.
В конечном счёте, я написал небольшую программу на Перле, чтобы вывести строку на русском:
#!/usr/bin/perl
use Text::Iconv;
my @codes = qw(
1110000 1110010 1101111
1111110 1101001 1110100
1100001 1101010 1110100
1100101 0100000 1100111
1101100 1100001 1110111
1110101 0100000 0100010
1110001 1111010 1111001
1101011 1101001 0100000
1110000 1110010 1101111
1100111 1110010 1100001
1101101 1101101 1101001
1110010 1101111 1110111
1100001 1101110 1101001
1110001 0100010
);
$conv = Text::Iconv->new("KOI-7", "UTF-8");
# ПРОЧИТАЙТЕ ГЛАВУ "ЯЗЫКИ ПРОГРАММИРОВАНИЯ"
print $conv->convert(chr oct "0b$_") for @codes, "\n";
Перл, конечно, малопопулярный язык, но тут вполне читаемый даже для тех, кто его не знает. Его я выбрал из-за лени — у него есть конструкция qw( … ), которая позволяет создавать массивы из строк без кавычек и запятых, так что в него просто было удобно запихнуть закодированный текст, каким он получился после распознавания.
В конечном счёте раскодированный текст выглядит так: ПРОЧИТАЙТЕ ГЛАВУ "ЯЗЫКИ ПРОГРАММИРОВАНИЯ". Лобастый Новосельцев немного нас обманывает.