Патина кода: восстановление и документация ПО с магнитных лент и перфолент
Когда в руки попадает кусок истории в виде магнитной ленты или перфоленты, это уже не просто носитель — это артефакт, который хранит уникальный код, алгоритмы и стиль эпохи. В статье я расскажу о том, как можно оживить такие носители, как оцифровать данные, какие инструменты помогают расшифровать формат без документации, и почему документирование таких находок — не менее важная часть работы, чем их техническое восстановление.
Введение: запах пыли и шелест ленты
Я однажды держал в руках катушку с магнитной лентой, которую кто-то аккуратно подписал: «РЛС-88. ПО калибровки. 1983». В тот момент стало ясно: внутри этой катушки зашифрована маленькая Вселенная. Не только программа для радара, но и стиль мышления инженеров 80-х. Эти программы писали под железо, которого больше нет, в языках, у которых уже нет компиляторов. И вот перед тобой задача: не просто сохранить байты, а вытащить из них смысл.
Старые носители: как они жили и умирали
Магнитные ленты — это материал, который любит влажность и ненавидит время. Они расслаиваются, покрываются липким налётом, головки ридеров стирают дорожки. Перфоленты вроде бы вечные, но их угрожает банальная ломкость и пожелтевшая бумага. Считывать такое оборудование «в лоб» почти нереально: либо техника утрачена, либо требует реставрации.
Поэтому самый первый шаг — оцифровка сигнала. Иногда достаточно старого ленточного накопителя, но чаще приходится строить самодельный ридер. Например, для перфоленты — фотодиоды и LED-линейка, для ленты — датчик головки + АЦП.
Снятие сигнала и «сырые байты»
После того как лента пошла в ридер, на выходе вы получаете вовсе не «файл», а набор сырых битовых фрагментов. Это примерно как слушать музыку на виниле через микрофон: шумов и артефактов хватает. Нужно отделить полезный сигнал от мусора.
Здесь неожиданно выручают современные инструменты. Например, с помощью Python и библиотеки scipy можно обработать сигнал как аудиофайл: найти пики, восстановить частоту, а потом превратить в последовательность битов.
Пример (Python):
import numpy as np
from scipy.io import wavfile
from scipy.signal import find_peaks
# Загружаем оцифрованный сигнал (например, .wav с магнитофона)
fs, data = wavfile.read("tape_dump.wav")
# Нормализуем и убираем шум
signal = data / np.max(np.abs(data))
# Находим импульсы
peaks, _ = find_peaks(signal, height=0.5, distance=fs*0.001)
# Превращаем интервалы между пиками в биты
bits = []
for i in range(1, len(peaks)):
delta = peaks[i] - peaks[i-1]
bits.append(1 if delta < fs*0.002 else 0)
print("".join(map(str, bits[:200])))Этот кусок кода показывает, что восстановление — это почти криптография, где нет готового ключа.
Проблема форматов: а что там внутри?
Даже если удалось извлечь байты, дальше возникает новый уровень ада: формат. Чаще всего это не знакомый .exe или .txt, а что-то, придуманное конкретным отделом конкретного завода.
Структура может быть любой: последовательность команд процессора, бинарные блоки с контрольными суммами, странные кодировки. Здесь помогают две вещи:
Поиск повторяющихся сигнатур.
Реверс-инжиниринг на основе эмуляторов старых процессоров.
Например, можно взять дамп и загрузить его в Unicorn Engine (эмулятор CPU), чтобы попробовать исполнить. Это даёт подсказку, под какую архитектуру был собран код.
Документация как археология
Самое сложное — это не извлечь данные, а объяснить их. В старых проектах документация могла быть только на ватманах или в тетради инженера. Если повезёт, на катушке есть подпись. Если нет — приходится собирать историю по обрывкам.
Поэтому часть работы — это создание новой документации:
описание формата файла;
карта памяти или структуры блоков;
примеры кода на современном языке для анализа.
Пример:
// Пример структуры блока, найденного в дампе ленты
typedef struct {
uint16_t header; // Заголовок (0xAA55)
uint32_t timestamp; // Временная метка
uint8_t payload[64]; // Полезные данные
uint16_t crc; // Контрольная сумма
} tape_block;После такого можно хотя бы объяснить будущим исследователям, что внутри.
Почему это важно сегодня
Казалось бы, зачем мучиться с лентами, если у нас облака и GitHub? Но именно эти ленты могут хранить уникальный код: алгоритмы управления реакторами, баллистикой, авиацией. Иногда именно в этих байтах лежат решения, которые были сделаны впервые.
Кроме того, работа с такими носителями учит мыслить «ниже уровня абстракции». Современные программисты редко задумываются о том, как данные живут на железе, а здесь это ключевой навык.
Немного личной магии
Когда после часов мучений вдруг видишь первые распознанные байты, это похоже на раскопки археолога. Ты держишь в руках что-то, что не видели десятки лет. И именно это чувство — главное топливо в таких проектах. Оно заставляет сидеть ночами и писать парсеры, перепаивать датчики, искать драйверы для забытых микросхем.