VIC шифр является одним из самых сложных и карандашных бумажных шифров когда - либо придуманные. Используемый в 1950-х годах советским шпионом Рейно Хайяненом под кодовым названием «ВИКТОР», его основным принципом является безопасность через запутывание; много запутывания.
Ваша задача - написать программу или функцию, которая будет принимать сообщение и кодировать его с помощью шифра VIC. Я также разместил здесь проблему с шифровальным декодером VIC . Если какая-либо из следующих инструкций неясна, не стесняйтесь спрашивать о них в комментариях. Инструкции адаптированы с этого сайта .
Кодирование шифра VIC
подготовка
Вам понадобится пять входов:
- текстовое сообщение
- короткое ключевое слово или фраза, содержащая наиболее распространенные буквы на вашем языке
- ключевая фраза, такая как цитата или строка из песни (не менее 20 символов)
- дата (или другое число, которое состоит из шести цифр или более)
- номер личного агента
На практике эти последние четыре должны быть предварительно согласованы отправителем и получателем, включая вопрос о том, используется ли номер агента отправителя или получателя в кодировании.
Мой пример сообщения будет: We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.
Мы будем кодировать на английском языке (хотя вы можете использовать любой язык и алфавит), и наиболее распространенные буквы в английском алфавите A, E, I, N, O, R, S, T
. Я буду использовать ключевое слово SENATORI
.
Моя ключевая фраза - цитата Ричарда Фейнмана: «Первый принцип заключается в том, что вы не должны обманывать себя - и вы - самый легкий человек, чтобы обмануть».
В качестве даты я буду использовать 31 июля 2016 года (в формате 3172016
), то есть день, когда я написал это описание.
Личный номер, который я выбрал для себя 9
.
Краткое изложение шагов
- Получите промежуточные ключи для использования в следующих шагах.
- Построить и применить раскидистую шахматную доску.
- Построить и применить первую таблицу транспозиции.
- Построить и применить вторую (нарушенную) таблицу транспозиции.
- Завершите сообщение, вставив группу индикаторов сообщений.
Submechanisms
Еще две вещи, которые нужно объяснить, прежде чем мы углубимся в суть вопроса: процессы сложения цепочек и секвенирования.
Цепное сложение, также известное как отставший генератор Фибоначчи, работает, беря последовательность начальных цифр, добавляя первые две цифры без переноса (затем сложите их вместе mod 10
) и добавляя результат в конец. Например:
79081
7 + 9 = 6
790816
9 + 0 = 9
7908169
0 + 8 = 8
79081698
8 + 1 = 9
790816989
1 + 6 = 7
7908169897
... and so on
Последовательность - это, по сути, последовательность букв или цифр и их маркировка в алфавитном / числовом порядке. Дубликаты помечены слева направо. Например:
E X A M P L E
0 # A
1 0 2 # Es
1 0 3 2 # L
1 0 4 3 2 # M
1 0 4 5 3 2 # P
1 6 0 4 5 3 2 # X
3 3 0 5 8 4 2 0 4 7 5 4 8 1
0 1 # 0s
0 1 2 # 1
0 3 1 2 # 2
4 5 0 3 1 2 # 3s
4 5 0 6 3 1 7 8 2 # 4s
4 5 0 9 6 3 1 7 10 8 2 # 5s
4 5 0 9 6 3 1 7 11 10 8 2 # 7
4 5 0 9 12 6 3 1 7 11 10 8 13 2 # 8s
Я использую здесь нулевое индексирование, но индексирование, как вам нравится.
1. Промежуточные ключи
Разделите первые 20 букв ключевой фразы на две группы по 10 и секвенируйте каждую в отдельности, которую мы будем называть S1
и S2
.
THEFIRSTPR
S1: 8201357946
INCIPLEIST
S2: 2603751489
Выберите случайный 5-значный идентификатор сообщения M
(это может быть один из входных данных, если вы предпочитаете):
M = 47921
Вычтите без заимствования (вычтите mod 10
) первые пять цифр контрольной даты 3172016
из M
:
M 47921
date - 31720
= 16201
Цепочка добавить результат, пока у вас есть десять цифр:
1620178218
Добавьте эти цифры к S1
, без переноса или mod 10
, чтобы получить G
:
1620178218
S1 + 8201357946
G = 9821425154
Выше S2
напишите последовательность 0123456789. Найдите каждую цифру G
в последовательности 0123456789 и замените ее цифрой непосредственно под ней в S2
. Результат есть T
.
0123456789
S2 2603751489
G 9821425154
T 9806705657
Используйте цепочку, чтобы расширить T
до 60 цифр.
9806705657
becomes
980670565778637511245490262369939288595822106344304316978734
Эти последние 50 цифр в пяти рядах по десять цифр в каждом образуют U
блок.
T 9806705657
U 7863751124
5490262369
9392885958
2210634430
4316978734
Последние две неравные цифры U
блока по отдельности добавляются к личному номеру агента, чтобы задать ширину двух транспозиций, p
и q
.
9 + 3 = 12 (p, первая ширина транспонирования) 9 + 4 = 13 (q, вторая ширина транспонирования)
Упорядочить T
и использовать эту последовательность для копирования столбцов U
блока сверху вниз в новый ряд цифр V
.
T 9806705657
seqT 9804612537
U 7863751124
5490262369
9392885958
2210634430
4316978734
V 69911 56837 12548 26533 30206 13947 72869 49804 84323 75924
Упорядочить первые p
цифры, чтобы получить ключ для первой транспонирования K1
, и следующие q
цифры для ключа для второй K2
.
First 12 6 9 9 1 1 5 6 8 3 7 1 2
K1 6 10 11 0 1 5 7 9 4 8 2 3
Next 13 5 4 8 2 6 5 3 3 3 0 2 0 6
K2 8 7 12 2 10 9 4 5 6 0 3 1 11
Наконец, секвенируйте последнюю строку U
блока, чтобы получить C
заголовки столбцов для трансграничной шахматной доски:
U5 4316978734
C 3105968724
2. Шатаясь шахматная доска
Сначала я приведу пример шахматной доски, а затем объясню принципы ее создания следующим образом:
3 1 0 5 9 6 8 7 2 4
S E N A T O R I
2 B D G J L P U W Y .
4 C F H K M Q V X Z #
Первая строка букв - это наше короткое ключевое слово SENATORI
. Ваше ключевое слово может быть любой строкой без дубликатов, но, поскольку оно определяет верхний ряд вашей шахматной доски, выбирайте мудро. Над ключевым словом находится C
, а остальные строки - остальная часть вашего алфавита в любом порядке, который вы выберете. В моем случае я заполнил шахматную доску остальным латинским алфавитом, знаком пунктуации .
и знаком для разграничения чисел #
. По сути, шахматная доска является причудливым шифром замещения. Например, «E» будет замещен 1
, а «W» будет заменен 27
.
После того, как мы закодировали наше текстовое сообщение с помощью этой шахматной доски, но сначала нам нужно сделать начало нашего сообщения менее очевидным, разбив его на случайную позицию и сделав все заглавными. Чтобы обозначить другое оригинальное начало, мы используем две точки остановки..
We are discovered. Take what you can. Burn everything else. Move to Safehouse Foxtrot 3.
становится
HING ELSE. MOVE TO SAFEHOUSE FOXTROT#3#.. WE ARE
DISCOVERED. TAKE WHAT YOU CAN. BURN EVERYT
Мы кодируем с помощью шахматной доски, давая нам:
407020 1293124 496481 96 354114062831 416479869443442424 271 581
2173436481812124 95451 274059 22628 435024 232880 14818229
Если длина сообщения не делится на 5, мы добавляем несколько нулевых символов для дополнения сообщения. Наше сообщение длиной 109 цифр, поэтому я добавлю один ноль: «4».
40702 01293 12449 64819 63541 14062 83141 64798 69443 44242 42715
81217 34364 81812 12495 45127 40592 26284 35024 23288 01481 82294
Примечание. Поскольку мое примерное сообщение не содержит цифр, я скажу здесь, что вы можете указать, скажем, как #3#
, что закодировано как 44344
здесь.
3. Первая транспозиция
Создайте таблицу транспонирования, написав K1
(из раздела «Промежуточные ключи»), а затем закодированное сообщение из предыдущего шага в строках одинаковой длины под ключом:
K1 6 10 11 0 1 5 7 9 4 8 2 3
4 0 7 0 2 0 1 2 9 3 1 2
4 4 9 6 4 8 1 9 6 3 5 4
1 1 4 0 6 2 8 3 1 4 1 6
4 7 9 8 6 9 4 4 3 4 4 2
4 2 4 2 7 1 5 8 1 2 1 7
3 4 3 6 4 8 1 8 1 2 1 2
4 9 5 4 5 1 2 7 4 0 5 9
2 2 6 2 8 4 3 5 0 2 4 2
3 2 8 8 0 1 4 8 1 8 2 2
9 4
Взяв пронумерованные столбцы в порядке их номеров, мы получим:
060826428 246674580 151411542 246272922 961311401 082918141
4414434239 118451234 334422028 293488758 0417249224 794943568
4. Вторая транспозиция
Первая транспозиция была относительно простой. Этот, однако, является нарушенным транспонированием. Схема разрушения определяется шириной таблицы и ключа. В нашем примере у нас есть 110 цифр и 13 столбцов, что означает, что у нас будет 8 полных строк и 6 остатков. Мы начинаем заполнять первый ряд, но останавливаемся в столбце 0 и продолжаем следующим образом:
K2 8 7 12 2 10 9 4 5 6 0 3 1 11
0 6 0 8 2 6 4 2 8 stop at 0
2 4 6 6 7 4 5 8 0 1 continue in a triangle pattern
5 1 4 1 1 5 4 2 2 4 6
2 7 2 9 2 2 9 6 1 3 1 1
4 0 1 0 8 2 9 1 8 1 4 1 4 until the end
4 1 4 4 3 4 2 3 9 1 1 restart and stop at 1
8 4 5 1 2 3 4 3 3 4 4 2
2 0 2 8 2 9 3 4 8 8 7 5 8
0 4 1 restart and stop at 2
Затем мы заполняем последние несколько пробелов оставшимися цифрами.
K2 8 7 12 2 10 9 4 5 6 0 3 1 11
0 6 0 8 2 6 4 2 8 7 2 4 9
2 4 6 6 7 4 5 8 0 1 2 2 4
5 1 4 1 1 5 4 2 2 4 6 7 9
2 7 2 9 2 2 9 6 1 3 1 1 4
4 0 1 0 8 2 9 1 8 1 4 1 4
4 1 4 4 3 4 2 3 9 1 1 9 4
8 4 5 1 2 3 4 3 3 4 4 2 3
2 0 2 8 2 9 3 4 8 8 7 5 8
0 4 1 5 6 8
Теперь мы зачитываем столбцы точно так же, как мы это делали при первом транспонировании.
71431148 42711925 861904185 22614147 45499243 28261334 80218938
641701404 025244820 645224398 271283226 94944438 064214521
И разбить все на 5-значные группы:
71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189
38641 70140 40252 44820 64522 43982 71283 22694 94443 80642 14521
5. Завершите сообщение
Последний шаг - вставить наш случайный идентификатор 47921
сообщения в само сообщение. Последняя цифра контрольной даты 6
указывает расстояние, которое группа должна быть от конца.
71431 14842 71192 58619 04185 22614 14745 49924 32826 13348 02189 38641
70140 40252 44820 64522 43982 47921 71283 22694 94443 80642 14521
Примечания к этой проблеме
- Вам предоставляется как минимум пять входных данных: сообщение, ключевое слово буквы, ключевая фраза, дата и личный номер. Вы можете включить два дополнительных ввода: идентификатор случайного сообщения и нули, необходимые для заполнения сообщения, или ваша функция может генерировать некоторые случайные числа самостоятельно.
- Можно предположить, что все входные данные верны, с правильным количеством цифр и букв (5-значный идентификатор сообщения, не менее 20 цифр для ключевой фразы и т. Д.). Вы можете предположить, что в ваших строках (сообщение и ключевые слова) уже удалены все знаки препинания и пробелы, кроме тех, которые вы разрешаете в своей версии, и что числа уже обозначены знаками чисел.
- В первом ключевом слове не должно быть повторяющихся букв, и в вашем коде вы можете предполагать, что в нем никогда не бывает повторяющихся букв.
- Язык, который вы используете для кодирования, не имеет значения, поскольку язык уже существует, алфавит уже существует, и вы указываете, какой язык вы используете в своем ответе.
- Какой бы алфавит вы ни использовали для своей шахматной доски, вы можете добавлять или удалять символы, чтобы дополнить шахматную доску. Укажите, для чего вы используете эти символы (например, знаки препинания, отдельный символ «начало сообщения», символы для общих слов). Вы можете полностью отказаться от знака числа и прописать числа или включить каждую цифру в шахматную доску, используя слот, где знак числа был для чего-то другого. Пожалуйста, укажите, какую шахматную доску вы использовали в своем ответе.
- Выходные данные должны быть либо строкой пятизначных групп, разделенных пробелами, списком пятизначных целых чисел или чем-то подобным.
- Я использовал нулевую индексацию и
0123456789
в моем примере. Вы можете использовать 1-индексирование и /1234567890
или другую систему в своем ответе, если вы укажете, что вы использовали.
Вот пример реализации на Ideone .
Это длинный пост, и я написал большую часть его вручную, поэтому, если в этом посте есть какие-то запутанные части или ошибки в подсчете и транспонировании, пожалуйста, дайте мне знать. Удачи и хорошего гольфа!
without borrowing
и without carrying
? Вы имеете в виду сложение и вычитание мода 10
, т.е. (6+7) mod 10 = 3
и (6-8) mod 10 = 8
?
adding the first two digits without adding
Ты имеешь в виду ношение?