Нейронные сети как метод хранения конфиденциальной информации

в 7:41, , рубрики: Алгоритмы, конфиденциальные данные, нейронные сети, ненормальное программирование, паранойя, метки: , , ,

Одним из применений нейронных сетей является ассоциативная память. Классический пример – хранение классификации каких-либо объектов по входным данным. Но немного модифицировав алгоритм взаимодействия с сетью, можно в ней хранить длинные строковые или бинарные данные, получаемые по ключ-паролю, что также позволяет добиться также добиться высокой криптоустойчивости данных

Предыстория

Решив освоить теорию нейронных сетей, я попытался найти какой-нибудь интересный вариант их применения. Первое что попалось на глаза – прогнозирование последующих состояний системы по её предыдущим состояниям. В голову пришло содержание какой-то научной статьи, в которой было написано о том, что последовательности цифр, выдаваемые человеческим мозгом могут быть спрогнозированны, т.е. по нескольким рандомным введенным числам можно угадать следующее загаданное число. Но увы однослойная нейронная сеть была неспособна на предугадывание с точностью выше 20%. И тогда в голову пришло нечто более интересное: ведь в виде матрицы весов нейронной сети можно хранить конфиденциальные данные, вроде паролей и ПИНов для карт, что для меня как для истиного паранойика показалось довольно привлекательной затеей.

Написание прототипа

Было принято решение использовать однослойный персептрон в качестве базы. Первым делом был написан прототип класса рассчета по матрице весов. Персептрон имеет по 256 (по колличеству символов в ASCII) нейронов во входном и скрытом слоях. На выходе же имеется один нейрон который выдает номер нейрона на котором получилась наибольшая сумма. Значения весов было решено хранить в матрице omega[i, j], где i – номер нейрона скрытого уровня, а j – номер связи. На вход подается строка из 5 символов (опытным путем было выявлено, что это наиболее оптимальный вариант). Таким образом вычисление выходного символа сводится к двум функциям: преобразование входной строки во массив входных нейронов и выделение выходного символа исходя из входных нейронов и матрицы весов.

Предварительные преобразования

Если принять что, чем правее находится символ в исходной строке, тем более он влияет на последующие символы, то получаем простую функцию преобразования строки в массив «сигналов» входного слоя. К примеру для входной строки «17345» получаем массив k, в котором k['1'] = 1; k['7'] = 2 и т.д.

Рассчет выхода

Рассчет выхода делается столь же просто. Все сводится к циклу вида:

        public int[] OmegaProcessing(int[] _in)
        {
            int[] o = new int[256];
            for (int i = 0; i <= 255; i++)
                for (int j = 0; j <= 255; j++)
                    o[i] = omega[i, j] * _in[j] + o[i];
            return o;
        }

Где входящий массив _in[] есть выходной массив k[] из предыдущей функции.
После рассчета сигналов нейронов скрытого уровня (выходной массив o[]), выбираем из него максимальный. Он и будет искомым выходным символом.

Кодирование информации

Кодировать мы будем строки. Соответственно наша цель это обучить нейронную сеть на «предсказание» информации по ключ-паролю. В качестве прогнозируещего метода будет использоваться метод окон (применяемый при прогнозирование валютных изменений). Соответственно алгоритм обучения выглядит так:
1) Берется 5 первых символов строки и проводится вычисление.
2) Сравнивается со следующим символом входящей строки и по надобности проводится обучение (перестановка весов).
3) Пункты 1 и 2 повторяются со смещением на один символ правее до конца входящей строки.

Соответственно нужно правильно составить строку для обучения.
Пример:
paswd+++Hello habr! It's me!

Структура:
1) paswd – ключ-фраза (взято именно 5 символов, для простоты реализации)
2) +++ – три проверочных символа (о них ниже)
3) Hello habr! It's me! – кодируемая фраза
4) – терминатор; конец кодируемой фразы

На этом трудности кодирвания заканчиваются, но ведь еще информацию надо восстановить.

Декодирование информации

Декодирование должно производится с единственной входной информацией в виде ключ-пароля.

Первичная проверка

Первым делом нужно проверить не введены ли совершенно некоректные данные. Поэтому нам надо восстановить те самые три проверочных символа. Подаем на вход пять символов пароля. Получаем первый символ. Формируем новый вход: четыре символа от пароля + символ проверки. Получаем второй символ и сравниваем с первым. Тоже самое повторяем с третьим. Если все верно, то получившаяся для последующих интераций входная строка будет состоять из 2 символов пароля и три символа проверки.

Восстановление информации

Далее будем проводить такие же интерации пока не встретиться символ-терминатор. В каждой последовательной интерации у входной строки отнимается первый символ и прибавляется предыдущий выходной символ. Каждый выходной символ также добавляется к строке вывода. Таким образом, дойдя до терминального символа, мы получим закодированную строку на выходе.

Хранение нейронной сети

Последним неучтенным моментом является то, как мы будем хранить полученную сеть с нашей информацией. Т.к. реализацию я делал на C#, то было решено что хранить мы будем хранить данные в виде бинарного файла с записанным в него сериализованным массивом весов (тот самый omega[,]). Таким образом мы получаем файл весом в 256Кб с записанными нами данными.

Еще немного цифр

Может показаться избыточным хранить небольшие строки в таком объемном файле. Но на это я могу возразить. На тестовую строку используемую в статье у сети вышло 23 интерации при обучении. Для хранения больших объемов информации (множество пинов и паролей через запятую = около 100 символов) понадобилось около 2500 интераций. В некоторых исключительных ситуациях (часто повторяющиеся короткие последовательности) было невозможно провести обучение, т.к. даже пройдя максимально возможное интераций обучения (Int32.Max), сеть не могла восстановить строку на 100%
Следовательно, возвращаясь к возражениям: во-первых можно хранить и большие объемы, чем показанный в статье пример, во-вторых такой способ может продемонстрировать довольно высокую криптоустойчивость, хотя эту самую устойчивость еще надо испытывать и испытывать.

Автор: dabar347

Источник

Поделиться

* - обязательные к заполнению поля