TL; DR
Для небольших файлов это легко, для файлов в диапазоне 60-200 КБ это все еще возможно, для больших файлов - безнадежно.
Ноль или одна случайная новая строка повреждены
Легко движется.
Этот сценарий грубой силы bash, построенный на однострочном Perl, предоставленном @Denizв своем ответе работал над файлом, который потерял всего одну случайную новую строку после того, что за магическим числом:
lines=`wc -l < image.corrupted.png`
for x in `seq 1 $((lines+1))`; do
echo -n $x ''
perl -pe 's/$/$1\r/ if ($. == 1 || $. =='$x')' < image.corrupted.png > image.fixed.png
if pngcheck image.fixed.png; then
echo Valid file substituting newline numbers 1 and $x
break
fi
done
Файл был размером 97 КБ, и это заняло около 11 с.
Два случайных перевода новой строки повреждены
Будьте терпеливы.
Это должно работать при отсутствии двух случайных символов новой строки плюс начальный:
lines=`wc -l < image.corrupted.png`
foundit=
for x in `seq 3 $((lines+1))`; do
date
echo $x
time for y in `seq 3 $((lines+1))`; do
echo -n $y ''
perl -pe 's/$/$1\r/ if ($. == 1 || $. =='$x' || $. =='$y')' < image.corrupted.png > image.fixed.png
if pngcheck image.fixed.png; then
echo Valid file substituting newline numbers 1, $x and $y
foundit=1
break
fi
done
if [[ $foundit ]]; then
break
fi
done
Потребовалось 2 минуты, чтобы завершить одну итерацию внутреннего цикла, и полтора дня, чтобы найти фиксированное изображение.
Если ваш файл меньше 200 КБ, у вас может быть некоторая надежда на этоподход, если вам повезло, что не более 2 случайных новых строк были повреждены, но от 3 раслучайные переводы строк безнадежны.Помните, что вы ожидаете в среднем один случайный поврежденный перевод строки на 64 КБ.Поэтому, конечно, если вам не повезло, даже в меньшем файле могло быть больше CRLF.
Три или более случайных символа новой строки повреждены
Просто забудьте об этом!
У меня есть файл размером 464 КБ, с которым я играю, и я знаю, что 3 случайных символа новой строки были повреждены (случайно меньше, чем ожидалось, я думаю, мне повезло), кроме одного настрока 1 (в магическом числе), и моя оценка состоит в том, что потребуется 4 года, чтобы найти правильную комбинацию с подходом грубой силы.Я не в бизнесе!
В этом случае я работаю с 3-х глубокой версией этой грубой силовой петли.Я собираюсь дать ему поработать несколько дней ради удовольствия, но я не ожидаю, что он что-то найдет, так как я не хочу позволить ему работать в течение 4 лет ...
Фон
Приведенные выше сценарии основаны на следующих предположениях:
Заголовок
Файлы PNG имеют магическое число - 8-заголовок байта - который содержит две новые строки, одну в формате CRLF в стиле Dos и одну LF в стиле Unix.Они существуют именно для того, чтобы выявлять искажения в результате перевода строки.Поэтому исправление файла потребует исправления магического числа, например, используя решение, предоставленное @Deniz в его ответе.
Ссылка: https://en.wikipedia.org/wiki/Portable_Network_Graphics#File_header
Тело
Тело файла PNG сжато, и поэтому мы можем ожидать высокого энтропийного случайного распределения байтов и пар байтов в нем, например, равномерное распределение.(Это то, к чему стремятся алгоритмы сжатия, в конце концов!) Таким образом, мы можем ожидать в среднем 1 символ новой строки на 256 байтов, и в среднем 1 из 256 из них будет CRLF.Таким образом, у нас есть в среднем один LF для преобразования обратно в CRLF на 64 КБ файла PNG.
pngcheck
Программа pngcheck
(среди прочих яобязательно) может использоваться для проверки действительности файла PNG, включая его магический номер и контрольную сумму, хранящуюся в файле.Таким образом, мы можем использовать, чтобы узнать, когда мы обнаружили, какие LF были изначально CRLF.
«Правильное» решение
Хорошее решение этой проблемы будет использовать дальнейшее знаниеформат данных и принять обоснованное решение для каждой новой строки.Например, можно проанализировать два потока распакованных данных, полученных в результате рассмотрения еще нескольких десятков байтов после каждой новой строки, предполагая, что новая строка изначально была LF или CRLF соответственно.При глубоком знании формата данных или, возможно, некоторого машинного обучения, это должно быть возможно ...
Решение для перебора
Не имея глубокого понимания формата файла PNG, можно восстановить небольшие файлы с помощью грубой силы, попробовав все комбинации преобразования до двух случайно поврежденных строк новой строки обратно в CRLF.Однако вычислительные затраты являются экспоненциальными в количестве CRLF в исходном файле, поэтому обобщение подхода за пределы двух искаженных случайных строк новой строки не имеет смысла.