Compare commits

...

10 Commits

Author SHA1 Message Date
NaiJi ✨ 9baf689f84 Add 'LICENSE' 2022-03-30 14:38:42 +00:00
NaiJi ✨ 83ae194e72 Update 'enigma_types.h' 2022-03-23 21:16:58 +00:00
NaiJi ✨ 7f4aa0f9a9 Update 'code.c.ino' 2022-03-23 21:16:29 +00:00
NaiJi ✨ 0e35915e62 Add README.md 2022-03-22 12:18:29 +00:00
NaiJi ✨ ab989d189a Fix encoding 2022-03-22 14:58:12 +03:00
NaiJi ✨ 1c4c94774d Fix iteration by wheels 2022-03-21 19:53:49 +03:00
NaiJi ✨ a1933c04df Update 'code.c.ino' 2022-03-17 20:25:21 +00:00
NaiJi ✨ dee279a789 Update 'enigma_types.h' 2022-03-17 20:24:56 +00:00
NaiJi ✨ 2bdc3f93c8 Replace strings for hex with Key structures 2022-03-17 19:33:58 +03:00
NaiJi ✨ e6b8d65949 Remove everything related to plugboard 2022-03-17 19:12:51 +03:00
4 changed files with 441 additions and 124 deletions

24
LICENSE Normal file
View File

@ -0,0 +1,24 @@
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>

5
README.md Normal file
View File

@ -0,0 +1,5 @@
# 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,78 +1,254 @@
#include <PS2KeyAdvanced.h> #include <LiquidCrystal_I2C.h>
#include "enigma_types.h" #include <PS2KeyAdvanced.h>
#include <Wire.h>
#define DATAPIN 2
#define IRQPIN 3 #include "enigma_types.h"
#include "HCuOLED.h"
PS2KeyAdvanced keyboard; #include "SPI.h"
// Сконвертировать HEX значение клавиши #define DATAPIN 4
// в её алфавитный индекс; #define IRQPIN 3
// #define CS_DI 10
// возвращает индекс буквы #define DC_DI 9
size_t toKeyIndex(const String& value) #define RST_DI 8
{
size_t index = -1; PS2KeyAdvanced keyboard;
for (size_t i = 0; i < ALPHABET_SIZE; ++i) HCuOLED HCuOLED(SH1106, CS_DI, DC_DI, RST_DI);
{
if (key_values[i] == value) LiquidCrystal_I2C lcd(0x27, 16, 2);
{ String lcd_output;
index = i;
break; uint16_t toKeyIndex(const String& input_hex)
} {
} uint16_t index = -1;
for (size_t i = 0; i < ALPHABET_SIZE; ++i)
return index; {
} if (key_values[i].hex == input_hex)
{
// Взять текущий сдвиг в алфавите. index = i;
// Считается суммарно по всем дискам в положении break;
// на момент вызова; }
// }
// возвращает текущий индекс с применением сдвига
size_t shift(size_t index) return index;
{ }
for (size_t i = 0; i < WHEELS_AMOUNT; ++i)
{ size_t forward1(size_t index, size_t current_wheel)
index += key_shifts[i]; {
} size_t input = (index + key_shifts[current_wheel]) % ALPHABET_SIZE;
return index % ALPHABET_SIZE; size_t output = 0;
} for (size_t i = 0; i < ALPHABET_SIZE; ++i)
{
// Зашифровать символ из алфавита if (mutations1[i].from == input)
// по алгоритму энигмы; {
// output = mutations1[i].to;
// возвращает зашифрованный символ для вывода break;
// на экран }
size_t encode(size_t index) }
{
// тут должно быть короче конвертирование по плагборду return output;
const size_t new_index = shift(index); }
// и вот тут тоже должноб ыть конвертирование по плагборду, ща
} size_t forward2(size_t index, size_t current_wheel)
{
///////////////////////////////////////////////////// size_t input = (index + key_shifts[current_wheel]) % ALPHABET_SIZE;
void setup() size_t output = 0;
{ for (size_t i = 0; i < ALPHABET_SIZE; ++i)
keyboard.begin(DATAPIN, IRQPIN); {
Serial.begin(115200); if (mutations2[i].from == input)
} {
output = mutations2[i].to;
void loop() break;
{ }
if (!keyboard.available()) }
return;
return output;
const uint16_t key = keyboard.read(); }
if (key <= 0)
return; size_t forward3(size_t index, size_t current_wheel)
{
const String value = String(key, HEX); size_t input = (index + key_shifts[current_wheel]) % ALPHABET_SIZE;
const size_t index = toKeyIndex(value);
if (index == -1) size_t output = 0;
return; for (size_t i = 0; i < ALPHABET_SIZE; ++i)
{
const size_t encoded_index = encode(index); 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;
}
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;
}
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()
{
if (!keyboard.available())
return;
const uint16_t key = keyboard.read();
if (key <= 0)
return;
const String value = String(key, HEX);
const uint16_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();
}

View File

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