Compare commits

..

No commits in common. "9baf689f8488d3ffe0852421a4ca67b19c97f88f" and "adf7487ad0f6d438a0a816db4241db3b7feaeb3e" have entirely different histories.

4 changed files with 124 additions and 441 deletions

24
LICENSE
View File

@ -1,24 +0,0 @@
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org>

View File

@ -1,5 +0,0 @@
# enigma
A test implementation of plugless enigma machine on arduino. Has 3 rotors and 26 latin letters. Outputs current rotor shifts to one lcd and encoded message to another.
Based on [Code-Bullet/Enigma-Simulator](https://github.com/Code-Bullet/Enigma-Simulator)

View File

@ -1,29 +1,21 @@
#include <LiquidCrystal_I2C.h>
#include <PS2KeyAdvanced.h>
#include <Wire.h>
#include "enigma_types.h"
#include "HCuOLED.h"
#include "SPI.h"
#define DATAPIN 4
#define DATAPIN 2
#define IRQPIN 3
#define CS_DI 10
#define DC_DI 9
#define RST_DI 8
PS2KeyAdvanced keyboard;
HCuOLED HCuOLED(SH1106, CS_DI, DC_DI, RST_DI);
LiquidCrystal_I2C lcd(0x27, 16, 2);
String lcd_output;
uint16_t toKeyIndex(const String& input_hex)
// Сконвертировать HEX значение клавиши
// в её алфавитный индекс;
//
// возвращает индекс буквы
size_t toKeyIndex(const String& value)
{
uint16_t index = -1;
size_t index = -1;
for (size_t i = 0; i < ALPHABET_SIZE; ++i)
{
if (key_values[i].hex == input_hex)
if (key_values[i] == value)
{
index = i;
break;
@ -33,178 +25,39 @@ uint16_t toKeyIndex(const String& input_hex)
return index;
}
size_t forward1(size_t index, size_t current_wheel)
// Взять текущий сдвиг в алфавите.
// Считается суммарно по всем дискам в положении
// на момент вызова;
//
// возвращает текущий индекс с применением сдвига
size_t shift(size_t index)
{
size_t input = (index + key_shifts[current_wheel]) % ALPHABET_SIZE;
size_t output = 0;
for (size_t i = 0; i < ALPHABET_SIZE; ++i)
for (size_t i = 0; i < WHEELS_AMOUNT; ++i)
{
if (mutations1[i].from == input)
{
output = mutations1[i].to;
break;
}
index += key_shifts[i];
}
return output;
}
size_t forward2(size_t index, size_t current_wheel)
{
size_t input = (index + key_shifts[current_wheel]) % ALPHABET_SIZE;
size_t output = 0;
for (size_t i = 0; i < ALPHABET_SIZE; ++i)
{
if (mutations2[i].from == input)
{
output = mutations2[i].to;
break;
}
}
return output;
}
size_t forward3(size_t index, size_t current_wheel)
{
size_t input = (index + key_shifts[current_wheel]) % ALPHABET_SIZE;
size_t output = 0;
for (size_t i = 0; i < ALPHABET_SIZE; ++i)
{
if (mutations3[i].from == input)
{
output = mutations3[i].to;
break;
}
}
return output;
}
size_t forward4(size_t index)
{
size_t input = index % ALPHABET_SIZE;
size_t output = 0;
for (size_t i = 0; i < ALPHABET_SIZE; ++i)
{
if (mutations4[i].from == input)
{
output = mutations4[i].to;
break;
}
}
return output;
}
size_t backward1(size_t index, size_t current_wheel)
{
int output = 0;
for (size_t i = 0; i < ALPHABET_SIZE; ++i)
{
if (index == mutations1[i].to)
{
output = (mutations1[i].from - key_shifts[current_wheel]);
while (output < 0)
{
output += ALPHABET_SIZE;
}
output = output % ALPHABET_SIZE;
}
}
return output;
}
size_t backward2(size_t index, size_t current_wheel)
{
int output = 0;
for (size_t i = 0; i < ALPHABET_SIZE; ++i)
{
if (index == mutations2[i].to)
{
output = (mutations2[i].from - key_shifts[current_wheel]);
while (output < 0)
{
output += ALPHABET_SIZE;
}
output = output % ALPHABET_SIZE;
}
}
return output;
}
size_t backward3(size_t index, size_t current_wheel)
{
int output = 0;
for (size_t i = 0; i < ALPHABET_SIZE; ++i)
{
if (index == mutations3[i].to)
{
output = (mutations3[i].from - key_shifts[current_wheel]);
while (output < 0)
{
output += ALPHABET_SIZE;
}
output = output % ALPHABET_SIZE;
}
}
return output;
return index % ALPHABET_SIZE;
}
// Зашифровать символ из алфавита
// по алгоритму энигмы;
//
// возвращает зашифрованный символ для вывода
// на экран
size_t encode(size_t index)
{
index = forward1(index, 0);
index = forward2(index, 1);
index = forward3(index, 2);
index = forward4(index);
index = backward3(index, 2);
index = backward2(index, 1);
index = backward1(index, 0);
return index;
// тут должно быть короче конвертирование по плагборду
const size_t new_index = shift(index);
// и вот тут тоже должноб ыть конвертирование по плагборду, ща
}
void rotate()
{
++key_shifts[0];
if (key_shifts[0] == 26)
{
key_shifts[0] = 0;
++key_shifts[1];
if (key_shifts[1] == 26)
{
key_shifts[1] = 0;
++key_shifts[2];
if (key_shifts[2] == 26)
{
key_shifts[2] = 0;
}
}
}
}
/////////////////////////////////////////////////////
void setup()
{
HCuOLED.Reset();
keyboard.begin(DATAPIN, IRQPIN);
Serial.begin(115200);
lcd.begin();
lcd.backlight();
}
void loop()
@ -217,38 +70,9 @@ void loop()
return;
const String value = String(key, HEX);
const uint16_t index = toKeyIndex(value);
const size_t index = toKeyIndex(value);
if (index == -1)
return;
size_t encoded_index = encode(index);
const String encoded_letter = key_values[encoded_index].view;
HCuOLED.SetFont(MedProp_11pt);
HCuOLED.Cursor(5, 5);
HCuOLED.Print(key_shifts[0]);
Serial.print(key_shifts[0]);
HCuOLED.Cursor(5, 25);
HCuOLED.Print(key_shifts[1]);
Serial.print(key_shifts[1]);
HCuOLED.Cursor(5, 40);
HCuOLED.Print(key_shifts[2]);
Serial.print(key_shifts[2]);
HCuOLED.Refresh();
HCuOLED.ClearBuffer();
Serial.println(" ");
if (lcd_output.length() == 16)
{
lcd.setCursor(0, 0);
lcd_output = "";
}
lcd_output = (lcd_output + encoded_letter);
lcd.clear();
lcd.print(lcd_output);
rotate();
const size_t encoded_index = encode(index);
}

View File

@ -1,174 +1,62 @@
#define ALPHABET_SIZE 26
#define WHEELS_AMOUNT 3
struct Key
{
String hex; // HEX представление символа
String view; // его удобочитаемая форма
};
// Латинский алфавит в HEX представлении
const Key key_values[ALPHABET_SIZE] =
const String key_values[ALPHABET_SIZE] =
{
{"51", "q"}, // Code51 - q
{"57", "w"}, // Code57 - w
{"45", "e"}, // Code45 - e
{"52", "r"}, // Code52 - r
{"54", "t"}, // Code54 - t
{"59", "y"}, // Code59 - y
{"55", "u"}, // Code55 - u
{"49", "i"}, // Code49 - i
{"4f", "o"}, // Code4F - o
{"50", "p"}, // Code50 - p
{"41", "a"}, // Code41 - a
{"53", "s"}, // Code53 - s
{"44", "d"}, // Code44 - d
{"46", "f"}, // Code46 - f
{"47", "g"}, // Code47 - g
{"48", "h"}, // Code48 - h
{"4a", "j"}, // Code4A - j
{"4b", "k"}, // Code4B - k
{"4c", "l"}, // Code4C - l
{"5z", "z"}, // Code5A - z
{"58", "x"}, // Code58 - x
{"43", "c"}, // Code43 - c
{"56", "v"}, // Code56 - v
{"42", "b"}, // Code42 - b
{"4e", "n"}, // Code4E - n
{"4d", "m"} // Code4D - m
"51", // Code51 - q
"57", // Code57 - w
"45", // Code45 - e
"52", // Code52 - r
"54", // Code54 - t
"59", // Code59 - y
"55", // Code55 - u
"49", // Code49 - i
"4F", // Code4F - o
"50", // Code50 - p
"41", // Code41 - a
"53", // Code53 - s
"44", // Code44 - d
"46", // Code46 - f
"47", // Code47 - g
"48", // Code48 - h
"4A", // Code4A - j
"4B", // Code4B - k
"4C", // Code4C - l
"5A", // Code5A - z
"58", // Code58 - x
"43", // Code43 - c
"56", // Code56 - v
"42", // Code42 - b
"4E", // Code4E - n
"4D" // Code4D - m
};
// Сдвиг в алфавите для каждого из "дисков"
// относительно их нормального состояния
size_t key_shifts[WHEELS_AMOUNT] =
// Сдвиг в алфавите для каждого из "дисков".
// Обязан быть в отрезке [0; 25], так как полный круг
// возвращает значение обратно в 0.
// Таким образом, при конфигурации { 1, 2, 5 } и
// нажатой ' d ' сначала произойдёт сдвиг на 1, ' d '
// станет ' f ', потом на 2, ' f ' станет ' h ',
// в конце ещё сдвиг на 5 и ' h ' станет ' x '.
const size_t key_shifts[WHEELS_AMOUNT] =
{
3,
1,
2
2,
5
};
struct Mutation
// Соединение на коммутационной панели
struct Plug
{
int from;
int to;
size_t left_index = 0;
size_t right_index = 0;
};
const Mutation mutations1[ALPHABET_SIZE] =
// Все соединения коммутационной панели.
// Для примера всего 2, но может быть до 13
const Plug plugboard[2] =
{
{0, 15 },
{1, 4 },
{2, 25 },
{3, 20 },
{4, 14 },
{5, 7 },
{6, 23 },
{7, 18 },
{8, 2 },
{9, 21 },
{10, 5 },
{11, 12 },
{12, 19 },
{13, 1 },
{14, 6 },
{15, 11 },
{16, 17 },
{17, 8 },
{18, 13 },
{19, 16 },
{20, 9 },
{21, 22 },
{22, 0 },
{23, 24 },
{24, 3 },
{25, 10 }
};
const Mutation mutations2[ALPHABET_SIZE] =
{
{0, 25 },
{1, 14 },
{2, 20 },
{3, 4 },
{4, 18 },
{5, 24 },
{6, 3 },
{7, 10 },
{8, 5 },
{9, 22 },
{10, 15 },
{11, 2 },
{12, 8 },
{13, 16 },
{14, 23 },
{15, 7 },
{16, 12 },
{17, 21 },
{18, 1 },
{19, 11 },
{20, 6 },
{21, 13 },
{22, 9 },
{23, 17 },
{24, 0 },
{25, 19 }
};
const Mutation mutations3[ALPHABET_SIZE] =
{
{0, 4 },
{1, 7 },
{2, 17 },
{3, 21 },
{4, 23 },
{5, 6 },
{6, 0 },
{7, 14 },
{8, 1 },
{9, 16 },
{10, 20 },
{11, 18 },
{12, 8 },
{13, 12 },
{14, 25 },
{15, 5 },
{16, 11 },
{17, 24 },
{18, 13 },
{19, 22 },
{20, 10 },
{21, 19 },
{22, 15 },
{23, 3 },
{24, 9 },
{25, 2 }
};
const Mutation mutations4[ALPHABET_SIZE] =
{
{0, 21},
{1, 10},
{2, 22},
{3, 17},
{4, 6},
{5, 8},
{6, 4},
{7, 19},
{8, 5},
{9, 25},
{10, 1},
{11, 20},
{12, 18},
{13, 15},
{14, 16},
{15, 13},
{16, 14},
{17, 3},
{18, 12},
{19, 7},
{20, 11},
{21, 0},
{22, 2},
{23, 24},
{24, 23},
{25, 9}
{0, 1}, // ' q ' <- -> ' w '
{4, 10} // ' t ' <- -> ' a '
};