! c 2013 .

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 секунд.. А это очень долго!

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

 

 

 

Результат работы:

 

Исходный текст:

Зашифрован:

Расшифрован: