BrainFuck шифрование (Часть 1)
18 2012
Пришло время сотворить нечто новое и никому ненужное :D
Хотя, вероятно, любителям извращаться/шифровать/**ать_мозг это может пригодиться.
В этом посту могу позволить себе любые нецензурные фразы, раз уж я развиваю тему BrainFuck, что в дословном переводе на русский, звучит примерно как "**ать Мозг".
Давно уже хотелось разработать свой уникальный метод шифрования.. Но то, что приходило на ум ранее - не содержало настолько интересные методы как в случае с BrainFuck.
Уверен, старина Алан Тюринг в 1936 году, когда предложил миру полностью универсальный вариант расширенного конечного автомата,
позволяющего запрограммировать абсолютно любой алгоритм, не мог и предположить, что его идея выльется в нечто подобное..
Хотя, сама реализация Машины Тюринга в виде BrainFuck на мой взгляд самая интуитивно понятная, и наглядная, но как и откуда появилось такое название..
Заранее оговорюсь:
Сегодняшний код не претендует на высокую оценку, он был набран ради фана.
Более того, часть методов с уверенностью можно назвать быдло-кодом.
Но разве это не прекрасно? Желающие могут доработать представленный далее класс, получив в итоге уникальный алгоритм шифрования, который можно будет применять в своих разработках.
В следующей части данной темы (примерно через месяц) я представлю отлаженный, грамотный, качественный класс по шифрованию путем использования BrainFuck.
Задача:
Создать шифратор/дешифратор, использующий язык BrainFuck.
Этапы реализации:
1) BrainFuck-генерация
2) BrainFuck-оптимизация
3) Шифрование
4) Дешифрование
5) BrainFuck-интерпретация
Приступаем:
Разумеется в данной реализации Машины Тюринга я не мог себе позволить бесконечную ленту, т.к. к этому моменту человечество еще не сумело разработать бесконечный объем памяти, поэтому решил, что 2^22 будет достаточно..
Объявляем:
Скажу честно: когда появилась необходимость определять, является ли символ числом - было лень искать стандартные функции с++,
решил, что проще написать свой метод:
Интерфейс класса:
1) BrainFuck-генерация
Итак, как будет происходить процесс генерации BrainFuck кода?
К примеру нам требуется сгенерировать BF-код строки "abc", которой соответствуют следующие коды символов: 97 98 99
Разумеется что получив символ "a", остальные можно вывести следующим образом:
+.+.
Но я решил, что для начала лучше делать так:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++.>+++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++.>
++++++++++++++++++++++++++++++++.>++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++.>+++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++.>
т.е. после инкрементов до определенного символа, происходит переход к следующей ячейке памяти и снова с нуля инкрементирует её значение до очередного символа.
Да.. Но пока что будет так, потому что на таком BrainFuck-коде будет удобно рассматривать методы его оптимизации.
2) BrainFuck-оптимизация:
Первый метод, который приходит в голову - циклы.
т.е. вместо 100 символов "+", что соответствует символу "d", создать цикл "10 по 10". Вот так:
>++++++++++[<++++++++++>-]<.
Уже лучше, не так ли?
Заменять циклами будем только если длина ряда превышает 10.
Что делать, если код символа к примеру 111?
Я решил задачу так:
1) Извлекаем корень из кода символа.
2) Вычитаем из кода символа квадрат корня - получаем количество символов, которых нехватает.
3) Вычитаем из кода символа квадрат корня+1 - получаем количество символов, которые необходимо вычесть.
4) Выбираем вариант с наименьшим количеством символов и реализуем цикл с инкрементом/декрементом нехватающих/лишних +/-
Сам метод:
На этом и завершится этап оптимизации.
3) Шифрование
Сдесь уже все зависит от вашей фантазии.
Я считаю, если зашифровать XOR'ом - будет достаточно.
Но сегодня зашифруем следующим способом:
1) Все символы "+" заменять на "+" + их количество
2) Все символы "-" заменять на "-" + их количество
т.е. код
>++++++++++[<++++++++++>-]<.
в зашифрованном виде будет выглядеть так:
>+10[<+10>-]<.
Метод генерации с оптимизацией и шифрованием:
4) Дешифрование
Дешифрование сводится к замене числа-количества плюсов/минусов
на ряд плюсов/минусов, т.е.
+10 = ++++++++++
При обнаружении плюса/минуса, будем проверять является ли следующий за ним символ цифрой, если да, то проверять и следующий за ним.
Этого будет достаточно, т.к. в нашем случае количество цифр в числе не может превышать 2.
5) BrainFuck-интерпретация
Интерпретация будет происходить посимвольно, если встречается цикл - будет происходить рекурсивный вызов функции, интерпретурующей символ.
Вот собственно сама функция:
И сама интерпретация:
Подведем итоги:
У нас есть рабочий класс-генератор-оптимизатор-шифратор-дешифратор-интерпретатор BrainFuck-кода
Не обязательно ограничиваться одним уровнем шифрования! Зашифрованный код можно зашифровать еще несколько раз.
Правда 3-ий уровень шифрования 20-ти-символьной строки длится от 10 до 30 секунд.. А это очень долго!
Так что мне предстоит доработать этот класс, улучшить генерацию, разработать качественный оптимизатор и серьезный шифратор.
Результат работы: