diff --git a/Week0/.vscode/c_cpp_properties.json b/Week0/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..f912847 --- /dev/null +++ b/Week0/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x86", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "C:/MinGW/bin/gcc.exe", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x86", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/Week0/.vscode/launch.json b/Week0/.vscode/launch.json new file mode 100644 index 0000000..108e0f6 --- /dev/null +++ b/Week0/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": true, + "cwd": "c:/F/week0/ENIGMA/Week0", + "program": "c:/F/week0/ENIGMA/Week0/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/Week0/.vscode/settings.json b/Week0/.vscode/settings.json new file mode 100644 index 0000000..bb879da --- /dev/null +++ b/Week0/.vscode/settings.json @@ -0,0 +1,59 @@ +{ + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false +} \ No newline at end of file diff --git a/Week0/Enigma-Machine Project b/Week0/Enigma-Machine Project new file mode 160000 index 0000000..3bed2fc --- /dev/null +++ b/Week0/Enigma-Machine Project @@ -0,0 +1 @@ +Subproject commit 3bed2fc00737043b97a7f43b1c083f98577b9fd9 diff --git a/Week0/Enigma.js b/Week0/Enigma.js new file mode 100644 index 0000000..1bcae31 --- /dev/null +++ b/Week0/Enigma.js @@ -0,0 +1,194 @@ +/* + * File: Enigma.js + * --------------- + * This program implements a graphical simulation of the Enigma machine. + */ + +import "graphics"; +import "EnigmaConstants.js"; + +/* Main program */ + +function Enigma() { + var enigmaImage = GImage("EnigmaTopView.png"); + var gw = GWindow(enigmaImage.getWidth(), enigmaImage.getHeight()); + gw.add(enigmaImage); + runEnigmaSimulation(gw); +} + +// You are responsible for filling in the rest of the code. Your +// implementation of runEnigmaSimulation should perform the +// following operations: +// +// 1. Create an object that encapsulates the state of the Enigma machine. +// 2. Create and add graphical objects that sit on top of the image. +// 3. Add listeners that forward mouse events to those objects. +var enigma={}; +function rotorRotation(enigma){ + var rotor = enigma.rotors[2]; + enigma.rotorOffset[2] = (enigma.rotorOffset[2] + 1) % 26; + var index = enigma.rotorOffset[2]; + rotor.setRotor(index); + if (index === 0) { + rotor = enigma.rotors[1]; + enigma.rotorOffset[1] = (enigma.rotorOffset[1] + 1) % 26; + index = enigma.rotorOffset[1]; + rotor.setRotor(index); + if (index === 0) { + rotor = enigma.rotors[0]; + enigma.rotorOffset[0] = (enigma.rotorOffset[0] + 1) % 26; + index = enigma.rotorOffset[0]; + rotor.setRotor(index); + } + } +} +function encryptLetter(letter, enigma) { + var index = letter.charCodeAt(0) - 65; + // Forward pass through rotors + for (var i = 2; i >= 0; i--) { + index = (index + enigma.rotorOffset[i]) % 26; + var c = ROTOR_PERMUTATIONS[i].charCodeAt(index) - 65; + index = c; + } + + // Reflector + index = REFLECTOR_PERMUTATION.charCodeAt(index) - 65; + + // Reverse pass through rotors + for (var i = 0; i < 3; i++) { + var letterAtIndex = String.fromCharCode(index + 65); + index = ROTOR_PERMUTATIONS[i].indexOf(letterAtIndex); + index = (index - enigma.rotorOffset[i] + 26) % 26; + } + rotorRotation(enigma); + return String.fromCharCode(index + 65); +} + +function runEnigmaSimulation(gw) { + enigma.keys = []; + enigma.lamps = []; + enigma.currKey = null; + enigma.currLamp = null; + enigma.rotors = []; + enigma.rotorOffset = []; + gw.addEventListener("mousedown", function(e) { + for(var i=0;i<3;i++){ + if(enigma.rotors[i].contains(e.getX(), e.getY())){ + var rotor = enigma.rotors[i]; + enigma.rotorOffset[i] = (enigma.rotorOffset[i] + 1) % 26; + var index = enigma.rotorOffset[i]; + rotor.setRotor(index); + break; + } + } + for(var i=0;i<26;i++){ + if(enigma.keys[i].contains(e.getX(), e.getY())){ + if(enigma.currLamp !==null){ + enigma.currLamp.turnOff(); + } + enigma.currKey = enigma.keys[i]; + enigma.currKey.mousedownAction(enigma); + break; + } + } + + }); + + gw.addEventListener("mouseup", function(e) { + if (enigma.currKey !== null) { + var letter = enigma.currKey.letter; + var encryptedLetter = encryptLetter(letter,enigma); + var lampIndex = encryptedLetter.charCodeAt(0) - 65; + enigma.currLamp = enigma.lamps[lampIndex]; + enigma.currLamp.turnOn(); + enigma.currKey.mouseupAction(enigma); + } + }); + + for(var i=0;i<3;i++){ + var loc = ROTOR_LOCATIONS[i]; + var rotor = new GRect(-ROTOR_WIDTH/2, -ROTOR_HEIGHT/2, ROTOR_WIDTH, ROTOR_HEIGHT); + rotor.setFilled(true); + rotor.setFillColor(ROTOR_BGCOLOR); + var label = new GLabel("A", -9, ROTOR_LABEL_DY); + label.setFont(ROTOR_FONT); + label.setColor(ROTOR_COLOR); + var rotorSetting = new GCompound(); + rotorSetting.add(rotor); + rotorSetting.add(label); + rotorSetting.label = label; + enigma.rotors.push(rotorSetting); + enigma.rotorOffset.push(0); + gw.add(rotorSetting,loc.x,loc.y); + rotorSetting.setRotor = function(index) { + var letter = String.fromCharCode(index + 65); + this.label.setLabel(letter); + this.label.setColor(ROTOR_COLOR); + }; + } + for(var i=0;i<26;i++){ + var letter = String.fromCharCode(i + 65); + (function(i){ + //Key Setup + var loc = KEY_LOCATIONS[i]; + var outer = new GOval(-KEY_RADIUS, -KEY_RADIUS, KEY_RADIUS * 2, KEY_RADIUS * 2); + outer.setFilled(true); + outer.setFillColor(KEY_BORDER_COLOR); + + var inner = new GOval(-KEY_RADIUS+KEY_BORDER, -KEY_RADIUS+KEY_BORDER,(KEY_RADIUS - KEY_BORDER) * 2, (KEY_RADIUS - KEY_BORDER) * 2); + inner.setFilled(true); + inner.setFillColor(KEY_BGCOLOR); + + var label = new GLabel(letter, -9, KEY_LABEL_DY); + label.setFont(KEY_FONT); + label.setColor(KEY_UP_COLOR); + + var key = new GCompound(); + key.add(outer); + key.add(inner); + key.add(label); + key.letter = letter; + gw.add(key,loc.x,loc.y); + enigma.keys.push(key); + key.mousedownAction = function(enigma) { + label.setColor(KEY_DOWN_COLOR); + }; + + key.mouseupAction = function(enigma) { + label.setColor(KEY_UP_COLOR); + enigma.currKey = null; + }; + + })(i); + + (function(i){ + //Lamp Setup + var loc = LAMP_LOCATIONS[i]; + var outer = new GOval(-LAMP_RADIUS, -LAMP_RADIUS, LAMP_RADIUS * 2, LAMP_RADIUS * 2); + outer.setFilled(true); + outer.setFillColor(LAMP_BORDER_COLOR); + var inner = new GOval(-LAMP_RADIUS+KEY_BORDER, -LAMP_RADIUS+KEY_BORDER,(LAMP_RADIUS - KEY_BORDER) * 2, (LAMP_RADIUS - KEY_BORDER) * 2); + inner.setFilled(true); + inner.setFillColor(LAMP_BGCOLOR); + var label = new GLabel(letter, -9, LAMP_LABEL_DY); + label.setFont(LAMP_FONT); + label.setColor(LAMP_OFF_COLOR); + var lamp = new GCompound(); + lamp.add(outer); + lamp.add(inner); + lamp.add(label); + lamp.label = label; + lamp.turnOn = function() { + this.label.setColor(LAMP_ON_COLOR); + this.setColor(LAMP_ON_COLOR); + }; + + lamp.turnOff = function() { + this.label.setColor(LAMP_OFF_COLOR); + this.setColor(LAMP_BORDER_COLOR); + }; + gw.add(lamp,loc.x,loc.y); + enigma.lamps.push(lamp); + })(i); + } +} diff --git a/Week0/EnigmaConstants.js b/Week0/EnigmaConstants.js new file mode 100644 index 0000000..7064b8d --- /dev/null +++ b/Week0/EnigmaConstants.js @@ -0,0 +1,144 @@ +/* + * File: EnigmaConstants.js + * ------------------------ + * This file defines the constants used in the Enigma simulator. + */ + +/* + * The early German Enigma machines include three rotors, which advance + * at different speeds. The rotor on the right is the "fast" rotor, + * which advances on every keystroke. The rotor in the middle is the + * "medium" rotor, which advances when the fast rotor has made a + * complete revolution. The rotor at the left is the "slow" rotor, + * which advances when the medium rotor has made a complete cycle. + * The ROTOR_PERMUTATION array lists the three rotors from left to + * right: the slow rotor, the medium rotor, and the fast rotor. + * + * Each rotor implements a letter-substitution cipher, which is + * represented by a string of 26 uppercase letters that shows how + * the letters in the alphabet are mapped to new letters as the + * internal signal flows across the rotor from right to left. For + * example, the slow rotor corresponds to the following mapping + * when it is in its initial position: + * + * A B C D E F G H I J K L M N O P Q R S T U V W X Y Z + * | | | | | | | | | | | | | | | | | | | | | | | | | | + * E K M F L G D Q V Z N T O W Y H X U S P A I B R C J + */ + +const ROTOR_PERMUTATIONS = [ + "EKMFLGDQVZNTOWYHXUSPAIBRCJ", /* Permutation for slow rotor */ + "AJDKSIRUXBLHWTMCQGZNPYFVOE", /* Permutation for medium rotor */ + "BDFHJLCPRTXVZNYEIWGAKMUSQO" /* Permutation for fast rotor */ +]; + +/* Constants that control the display of the current rotor setting */ + +const ROTOR_BGCOLOR = "#BBAA77"; /* Background color for the rotor */ +const ROTOR_WIDTH = 24; /* Width of the setting indicator */ +const ROTOR_HEIGHT = 26; /* Height of the setting indicator */ +const ROTOR_COLOR = "Black"; /* Text color of the rotor */ +const ROTOR_LABEL_DY = 9; /* Offset from center to baseline */ +const ROTOR_FONT = "Helvetica Neue-24"; + +/* This array specifies the coordinates of each rotor display */ + +const ROTOR_LOCATIONS = [ + { x: 244, y: 95 }, + { x: 329, y: 95 }, + { x: 412, y: 95 } +]; + +/* + * To the left of the slow rotor, the Enigma machine includes a + * component called the "reflector," which implements a fixed + * permutation that remains unchanged as the rotors advance. The + * constant REFLECTOR_PERMUTATION defines the mapping of the reflector. + * Note that the reflector is symmetric. If A is transformed to I, + * then I is transformed to A. + */ + +const REFLECTOR_PERMUTATION = "IXUHFEZDAOMTKQJWNSRLCYPBVG"; + +/* Constants that define the keys on the Enigma keyboard */ + +const KEY_RADIUS = 24; /* Outer radius of a key in pixels */ +const KEY_BORDER = 3; /* Width of the key border */ +const KEY_BORDER_COLOR = "#CCCCCC"; /* Fill color of the key border */ +const KEY_BGCOLOR = "#666666"; /* Background color of the key */ +const KEY_UP_COLOR = "#CCCCCC"; /* Text color when the key is up */ +const KEY_DOWN_COLOR = "#CC3333"; /* Text color when the key is down */ +const KEY_LABEL_DY = 10; /* Offset from center to baseline */ +const KEY_FONT = "Helvetica Neue-Bold-28"; + +/* This array determines the coordinates of a key for each letter index */ + +const KEY_LOCATIONS = [ + { x: 140, y: 566 } /* A */, + { x: 471, y: 640 } /* B */, + { x: 319, y: 639 } /* C */, + { x: 294, y: 567 } /* D */, + { x: 268, y: 495 } /* E */, + { x: 371, y: 567 } /* F */, + { x: 448, y: 567 } /* G */, + { x: 523, y: 567 } /* H */, + { x: 650, y: 496 } /* I */, + { x: 598, y: 567 } /* J */, + { x: 674, y: 567 } /* K */, + { x: 699, y: 641 } /* L */, + { x: 624, y: 641 } /* M */, + { x: 547, y: 640 } /* N */, + { x: 725, y: 497 } /* O */, + { x: 92, y: 639 } /* P */, + { x: 115, y: 494 } /* Q */, + { x: 345, y: 495 } /* R */, + { x: 217, y: 566 } /* S */, + { x: 420, y: 496 } /* T */, + { x: 574, y: 496 } /* U */, + { x: 395, y: 639 } /* V */, + { x: 192, y: 494 } /* W */, + { x: 242, y: 639 } /* X */, + { x: 168, y: 639 } /* Y */, + { x: 497, y: 496 } /* Z */ +]; + +/* Constants that define the lamps above the Enigma keyboard */ + +const LAMP_RADIUS = 23; /* Radius of a lamp in pixels */ +const LAMP_BORDER_COLOR = "#111111"; /* Line color of the lamp border */ +const LAMP_BGCOLOR = "#333333"; /* Background color of the lamp */ +const LAMP_OFF_COLOR = "#666666"; /* Text color when the lamp is off */ +const LAMP_ON_COLOR = "#FFFF99"; /* Text color when the lamp is on */ +const LAMP_LABEL_DY = 9; /* Offset from center to baseline */ +const LAMP_FONT = "Helvetica Neue-Bold-24"; + +/* This array determines the coordinates of a lamp for each letter index */ + +const LAMP_LOCATIONS = [ + { x: 144, y: 332 } /* A */, + { x: 472, y: 403 } /* B */, + { x: 321, y: 402 } /* C */, + { x: 296, y: 333 } /* D */, + { x: 272, y: 265 } /* E */, + { x: 372, y: 333 } /* F */, + { x: 448, y: 334 } /* G */, + { x: 524, y: 334 } /* H */, + { x: 650, y: 266 } /* I */, + { x: 600, y: 335 } /* J */, + { x: 676, y: 335 } /* K */, + { x: 700, y: 403 } /* L */, + { x: 624, y: 403 } /* M */, + { x: 549, y: 403 } /* N */, + { x: 725, y: 267 } /* O */, + { x: 94, y: 401 } /* P */, + { x: 121, y: 264 } /* Q */, + { x: 347, y: 265 } /* R */, + { x: 220, y: 332 } /* S */, + { x: 423, y: 265 } /* T */, + { x: 574, y: 266 } /* U */, + { x: 397, y: 402 } /* V */, + { x: 197, y: 264 } /* W */, + { x: 246, y: 402 } /* X */, + { x: 170, y: 401 } /* Y */, + { x: 499, y: 265 } /* Z */ +]; diff --git a/Week0/affine_cipher.cpp b/Week0/affine_cipher.cpp new file mode 100644 index 0000000..49e7673 --- /dev/null +++ b/Week0/affine_cipher.cpp @@ -0,0 +1,76 @@ +#include +#include +using namespace std; + +string toUpperCase(string str) { + for (char &c :str) { + c = toupper(c); + } + return str; +} + +string affineCipher(string text, int a, int b) { + string result = ""; + for (char c : text) { + char encryptedChar = char(((a * c + b) % 128)); + result += encryptedChar; + } + return result; +} + +bool coprime(int a, int b) { + while (b != 0) { + int t = b; + b = a % b; + a = t; + } + return a == 1; +} + +int getInverse(int a) { + for (int i = 1; i < 128; i++) { + if ((a * i) % 128 == 1) { + return i; + } + } + return -1; +} + +string decipher(string text, int a, int b) { + string result = ""; + for (char c : text) { + char encryptedChar = char(((c - b + 128) * a) % 128); + result += encryptedChar; + } + return result; +} + +int main(){ + string text; + int a,b; + cout<<"Enter the text to encrypt: "; + cin>>text; + cout<<"Enter the value of a: "; + cin>>a; + a%=128; + if(a<0) + a+=128; + if(coprime(a, 128)==false){ + cout<<"a and 128 are not coprime. Cannot encrypt."<>b; + b%=128; + if(b<0) + b+=128; + string enc = affineCipher(text, a, b); + cout<<"Encrypted text: "<=0.1.3 in c:\\users\\p9415\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from rsa->PySimpleGUI) (0.6.1)\n", + "Requirement already satisfied: serial in c:\\users\\p9415\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (0.0.97)\n", + "Requirement already satisfied: future>=0.17.1 in c:\\users\\p9415\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from serial) (1.0.0)\n", + "Requirement already satisfied: pyyaml>=3.13 in c:\\users\\p9415\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from serial) (6.0.2)\n", + "Requirement already satisfied: iso8601>=0.1.12 in c:\\users\\p9415\\appdata\\local\\programs\\python\\python313\\lib\\site-packages (from serial) (2.1.0)\n" + ] + } + ], + "source": [ + "# If you're using Google Colab or a local setup, run this line to install PySimpleGUI\n", + "!pip install PySimpleGUI\n", + "!pip install serial" + ] + }, + { + "cell_type": "markdown", + "id": "368a8fab", + "metadata": {}, + "source": [ + "Install Required Libraries" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "97c9b5e1", + "metadata": {}, + "outputs": [], + "source": [ + "import PySimpleGUI as sg\n", + "import serial\n", + "import time" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "50e5133d", + "metadata": {}, + "outputs": [], + "source": [ + "ser = serial.Serial('COM4', 115200, timeout=0.001)" + ] + }, + { + "cell_type": "markdown", + "id": "fddcb6aa", + "metadata": {}, + "source": [ + "### Task (for the code below):\n", + "\n", + "- Add three more text input sections for rotor1, rotor2, and rotor3.\n", + "\n", + "- Add a listbox to choose letters for the rotors from A" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "0384647a", + "metadata": {}, + "outputs": [], + "source": [ + "font_spec = 'Courier 24 bold'\n", + "heading_color = '#2FB8AD'\n", + "alphabet_list = list(\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\")\n", + "\n", + "# This defines how the GUI looks\n", + "layout = [\n", + " [sg.Text('Please Input Characters', background_color=heading_color)],\n", + " [sg.InputText('', key='pic_input'), sg.Button('Send', key='pic_send')],\n", + " [sg.Text('Rotor 1', background_color=heading_color),sg.Text(' '*54),\n", + " sg.Listbox(values=alphabet_list, size=(10, 1), enable_events=True, key='offset_1')],\n", + " [sg.InputText(key=\"rotor_1\"),sg.Button('Send', key='rotor1_send')],\n", + " [sg.Text('Rotor 2', background_color=heading_color),sg.Text(' '*54),\n", + " sg.Listbox(values=alphabet_list, size=(10, 1), enable_events=True, key='offset_2')],\n", + " [sg.InputText(key='rotor_2'),sg.Button('Send', key='rotor2_send')],\n", + " [sg.Text('Rotor 3', background_color=heading_color),sg.Text(' '*54),\n", + " sg.Listbox(values=alphabet_list, size=(10, 1), enable_events=True, key='offset_3')],\n", + " [sg.InputText(key='rotor_3'),sg.Button('Send', key='rotor3_send')],\n", + " [sg.Checkbox('Enable Reset', key='r_en'),sg.Button('Reset', key='rtg')],\n", + "]" + ] + }, + { + "cell_type": "markdown", + "id": "9d4c40f4", + "metadata": {}, + "source": [ + "### Apply Custom Theme to GUI\n", + "Task: Try changing colors! Make your GUI colorful! " + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "f37e74cf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sg.SetOptions(\n", + " background_color='#9FB8AD',\n", + " text_element_background_color='#9FB8AD',\n", + " element_background_color='#475841',\n", + " button_color=('white', '#475841'),\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "284faa59", + "metadata": {}, + "outputs": [], + "source": [ + "##Create and show the window\n", + "window = sg.Window('ECE4760 Interface', layout, finalize=True)\n", + "while True:\n", + " event, values = window.read(timeout=20)\n", + " \n", + " if event == sg.WIN_CLOSED or event == 'Exit':\n", + " break\n", + "\n", + " # Send typed message to PIC\n", + " if event == 'pic_send':\n", + " message = values['pic_input']\n", + " print(message)\n", + " #ser.write((message + '\\r').encode())\n", + " if event == 'rotor1_send':\n", + " settings= values['rotor_1']\n", + " print(settings)\n", + " if event == 'rotor2_send':\n", + " settings= values['rotor_2']\n", + " print(settings)\n", + " if event == 'rotor3_send':\n", + " settings= values['rotor_3']\n", + " print(settings)\n", + " if event == 'rtg' and values['r_en']:\n", + " print('reset done')\n", + " ser.send_break()\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ae99922", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "id": "a84bef37", + "metadata": {}, + "source": [ + "**Task**: Add event handling for `rotor1_send`, `rotor2_send`, and `rotor3_send`. Also, read serial data and show it in the `console`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cbed1be6", + "metadata": {}, + "outputs": [], + "source": [ + "# Reset only if checkbox is selected and RESET button clicked\n", + "if event == 'rtg' and values['r_en']:\n", + " ser.send_break() # sends a reset signal to the PIC" + ] + }, + { + "cell_type": "markdown", + "id": "e18bdfde", + "metadata": {}, + "source": [ + "**Task**: Add a checkbox called 'Enable Reset' and a button called 'RESET PIC'." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d8026f60", + "metadata": {}, + "outputs": [], + "source": [ + "# Close window after loop ends\n", + "window.close()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/Week0/logic.c b/Week0/logic.c new file mode 100644 index 0000000..9cee3c2 --- /dev/null +++ b/Week0/logic.c @@ -0,0 +1,363 @@ +#include +#include +#include +#include + +// Number of rotors and alphabet size +#define NUM_ROTORS 3 +#define ALPHABET_SIZE 26 + +// Rotor configurations (historical Enigma I rotors) +char rotors[NUM_ROTORS][ALPHABET_SIZE + 1] = { + "EKMFLGDQVZNTOWYHXUSPAIBRCJ", // Rotor I + "AJDKSIRUXBLHWTMCQGZNPYFVOE", // Rotor II + "BDFHJLCPRTXVZNYEIWGAKMUSQO" // Rotor III +}; + +// Reflector configuration (historical Enigma reflector B) +char reflector[ALPHABET_SIZE + 1] = "YRUHQSLDPXNGOKMIEBFZCWVJAT"; + +// Rotor offset positions (can be modified by user) +volatile int rotor_offsets[NUM_ROTORS] = {0, 0, 0}; // Right, middle, left + +// Turnover positions for each rotor (when the next rotor steps) +// Q, E, V for rotors I, II, III respectively (0-indexed) +int turnovers[NUM_ROTORS] = {'Q' - 'A', 'E' - 'A', 'V' - 'A'}; + +// Plugboard pairings (initialized to no swaps) +int pairings[ALPHABET_SIZE] = {0}; +int sketcherboard[ALPHABET_SIZE]={0}; +// Input and output buffers +char input_buffer[256] = {0}; +char output_buffer[256] = {0}; +bool sketcher_board_on=false; + +// To track stepping of rotors +int stepping[NUM_ROTORS] = {0, 0, 0}; + +// Convert a character to its 0-based index in the alphabet (A=0, B=1, etc.) +int char_to_index(char c) { + // Return the index of the letter in the alphabet (A=0, B=1, etc.) + return toupper(c) - 'A'; +} + +// Convert an index back to a character +char index_to_char(int index) { + // Convert an index (0-25) back to a character (A-Z) + return 'A' + (index % ALPHABET_SIZE); +} + +// Find the inverse mapping for a given rotor +int index_inverse(int c, int rotor) { + // This function finds the position in the rotor where the given + // character (as index + 'A') appears + int i; + for (i = 0; i < ALPHABET_SIZE; i++) { + if (rotors[rotor][i] == c + 'A') { + return i; + } + } + return -1; // Error condition +} + +// Map an input through a rotor from right to left +int rotor_r_to_l(int input, int rotor) { + // Apply offset to determine which contact is hit + int idx = (input + rotor_offsets[rotor]) % ALPHABET_SIZE; + + // Determine which contact it maps to, based on the rotor's wiring + int mapped = rotors[rotor][idx] - 'A'; + + // Adjust for the offset to get the index of the output contact + int res = mapped - rotor_offsets[rotor]; + + // Ensure the result is within range 0-25 + if (res < 0) res += ALPHABET_SIZE; + if (res >= ALPHABET_SIZE) res -= ALPHABET_SIZE; + + return res; +} + +// Map an input through a rotor from left to right +int rotor_l_to_r(int input, int rotor) { + // Apply offset to determine which contact is hit + int idx = (input + rotor_offsets[rotor]) % ALPHABET_SIZE; + + // Find the inverse mapping (which contact on the right maps to this one) + int inverse = index_inverse(idx, rotor); + + // Adjust for the offset to get the index of the output contact + int res = inverse - rotor_offsets[rotor]; + + // Ensure the result is within range 0-25 + if (res < 0) res += ALPHABET_SIZE; + if (res >= ALPHABET_SIZE) res -= ALPHABET_SIZE; + + return res; +} + +// Map an input through the reflector +int reflect(int input) { + // The reflector simply uses the lookup table to map the input + // to its corresponding output + return reflector[input] - 'A'; +} + +// Initialize the plugboard with given pairs +void initialize_plugboard(const char *pairs) { + // Reset the plugboard to no swaps + for (int i = 0; i < ALPHABET_SIZE; i++) { + pairings[i] = 0; + } + + // Process each pair + for (int i = 0; i < strlen(pairs); i += 3) { + if (pairs[i+1] == ' ' && i+2 < strlen(pairs)) { + // Extract the two letters to be paired + int first = toupper(pairs[i]) - 'A'; + int second = toupper(pairs[i+2]) - 'A'; + + if (first >= 0 && first < ALPHABET_SIZE && + second >= 0 && second < ALPHABET_SIZE) { + // Set up the bidirectional swap + pairings[first] = second - first; + pairings[second] = first - second; + } + } + } +} + +void initialize_sketcherboard(const char *pairs) { + // Reset the plugboard to no swaps + for (int i = 0; i < ALPHABET_SIZE; i++) { + pairings[i] = 0; + } + + // Process each pair + for (int i = 0; i < strlen(pairs); i += 3) { + if (pairs[i+1] == ' ' && i+2 < strlen(pairs)) { + // Extract the two letters to be paired + int first = toupper(pairs[i]) - 'A'; + int second = toupper(pairs[i+2]) - 'A'; + + if (first >= 0 && first < ALPHABET_SIZE && + second >= 0 && second < ALPHABET_SIZE) { + // Set up the bidirectional swap + sketcherboard[first] = second - first; + sketcherboard[second] = first - second; + } + } + } +} +// Swap a letter through the plugboard +int plug_swap(int input) { + // Add the offset (which may be 0 if no swap) to the input + if(sketcher_board_on) return input+sketcherboard[input]; + return input+pairings[input]; +} + +// Advance the rotors +void spin_rotors() { + if(rotor_offsets[0]==turnovers[0]){ + if(rotor_offsets[1]==turnovers[1]){ + rotor_offsets[2]=(rotor_offsets[2]+1)%ALPHABET_SIZE; + } + rotor_offsets[1]=(rotor_offsets[1]+1)%ALPHABET_SIZE; + } + else if(rotor_offsets[1]==turnovers[1]){ + rotor_offsets[2]=(rotor_offsets[2]+1)%ALPHABET_SIZE; + rotor_offsets[1]=(rotor_offsets[1]+1)%ALPHABET_SIZE; + } + rotor_offsets[0]=(rotor_offsets[0]+1)%ALPHABET_SIZE; +} + +// Simplified protothread structure for demonstration +struct pt { + int yield_state; +}; + +#define PT_BEGIN(pt) int yield_state = 0; switch(yield_state) { case 0: +#define PT_END(pt) } return 0; +#define PT_YIELD_TIME_msec(pt, ms) do { pt->yield_state = __LINE__; return 1; case __LINE__: } while(0); +#define PT_EXIT(pt) do { return 0; } while(0) + +// Encrypt a message using the PT_Encrypt thread +int PT_Encrypt(struct pt *pt, const char *input, char *output) { + PT_BEGIN(pt); + + int encrypt_idx = 0; + memset(output, '\0', 256); + + while (input[encrypt_idx] != '\0') { + // Skip non-alphabetic characters + if (!isalpha(input[encrypt_idx])) { + output[encrypt_idx] = input[encrypt_idx]; + encrypt_idx++; + continue; + } + + int res; + // Apply plugboard to the input character + res = plug_swap(char_to_index(input[encrypt_idx])); + + // Advance the rotors before encryption (once per character) + spin_rotors(); + + // Through the rotors from right to left + res = rotor_r_to_l(res, 0); // Right rotor + res = rotor_r_to_l(res, 1); // Middle rotor + res = rotor_r_to_l(res, 2); // Left rotor + + // Through the reflector + res = reflect(res); + + // Back through the rotors from left to right + res = rotor_l_to_r(res, 2); // Left rotor + res = rotor_l_to_r(res, 1); // Middle rotor + res = rotor_l_to_r(res, 0); // Right rotor + + // Apply plugboard again + res = plug_swap(res); + + // Store the result + output[encrypt_idx] = index_to_char(res); + + encrypt_idx++; + + // Yield to allow other threads to run + // PT_YIELD_TIME_msec(pt, 1000); + } + + // Terminate the thread + PT_EXIT(pt); + + PT_END(pt); +} + +// Simple encrypt character function (without threading) +char encrypt_char(char c) { + // If not a letter, return unchanged + if(c==' ' && sketcher_board_on){ + printf("Press-\n1)To continue using sketcher board\n2)To stop using sketcher board\n"); + int choice; + scanf("%d",&choice); + if(choice==2){ + sketcher_board_on=false; + } + } + if (!isalpha(c)) return c; + + // Convert to uppercase + c = toupper(c); + + // Advance the rotors + spin_rotors(); + + // Apply encryption logic + int res = char_to_index(c); + res = plug_swap(res); + res = rotor_r_to_l(res, 0); + res = rotor_r_to_l(res, 1); + res = rotor_r_to_l(res, 2); + res = reflect(res); + res = rotor_l_to_r(res, 2); + res = rotor_l_to_r(res, 1); + res = rotor_l_to_r(res, 0); + res = plug_swap(res); + + return index_to_char(res); +} + +// Simple encrypt message function (without threading) +void encrypt_message(const char *input, char *output) { + int i = 0; + while (input[i] != '\0') { + output[i] = encrypt_char(input[i]); + i++; + } + output[i] = '\0'; +} + +// Print current rotor positions +void print_rotor_status() { + printf("Rotor positions (L,M,R): %c %c %c\n", + index_to_char(rotor_offsets[2]), + index_to_char(rotor_offsets[1]), + index_to_char(rotor_offsets[0])); +} + +// Set rotor positions +void set_rotor_positions(char left, char middle, char right) { + rotor_offsets[2] = char_to_index(left); + rotor_offsets[1] = char_to_index(middle); + rotor_offsets[0] = char_to_index(right); +} + +// Example main function to demonstrate usage +int main() { + char command[10]; + char text[256]; + char plugboard_config[256] = ""; + char sketcher_board[256]=""; + struct pt pt_encrypt; + + printf("=== Enigma Machine Simulator ===\n\n"); + + while (true) { + print_rotor_status(); + printf("\nCommands:\n"); + printf("1: Set rotor positions\n"); + printf("2: Set plugboard configuration\n"); + printf("3: Encrypt a message\n"); + printf("4:Add sketcherboard settings\n"); + printf("5: Quit\n"); + printf("\nEnter command: "); + + scanf("%s", command); + if (command[0] == '1') { + char left, middle, right; + printf("Enter rotor positions (left middle right, e.g., 'A B C'): "); + scanf(" %c %c %c", &left, &middle, &right); + set_rotor_positions(left, middle, right); + printf("Rotor positions set to: %c %c %c\n\n", left, middle, right); + } + else if (command[0] == '2') { + printf("Enter plugboard pairs (e.g., 'A B C D' to swap A-B and C-D): "); + getchar(); // Clear newline + fgets(plugboard_config, sizeof(plugboard_config), stdin); + initialize_plugboard(plugboard_config); + printf("Plugboard configuration set\n\n"); + } + else if (command[0] == '3') { + printf("Enter message to encrypt: "); + getchar(); // Clear newline + fgets(text, sizeof(text), stdin); + text[strcspn(text, "\n")] = '\0'; // Remove newline + + encrypt_message(text, output_buffer); + printf("Encrypted message: %s\n\n", output_buffer); + + // Reset rotor positions for demonstration + printf("Note: Rotors have advanced during encryption.\n"); + + } + else if(command[0]=='4'){ + printf("Write the sketcher board setting.(e.g., 'A B C D' to swap A-B and C-D): "); + getchar(); // Clear newline + fgets(sketcher_board, sizeof(sketcher_board), stdin); + sketcher_board_on=true; + initialize_sketcherboard(sketcher_board); + printf("Sketcherboard configuration set\n\n"); + } + else if (command[0] == '5') { + printf("Exiting Enigma simulator.\n"); + break; + } + else { + printf("Invalid command. Please try again.\n\n"); + } + + } + + return 0; +} diff --git a/Week0/taskweek0/taskweek0.ino b/Week0/taskweek0/taskweek0.ino new file mode 100644 index 0000000..268b720 --- /dev/null +++ b/Week0/taskweek0/taskweek0.ino @@ -0,0 +1,53 @@ + +int pot1=A0; +int pot2=A1; +int bz1=3,bz2=4,bz3=5; +int white=8,green=9,yellow=10,orange=11,red=12; +int timer=0,led=0; +void setup() +{ + Serial.begin(9600); + pinMode(pot1, INPUT); + pinMode(bz1, OUTPUT); + pinMode(bz2, OUTPUT); + pinMode(bz3, OUTPUT); + + pinMode(pot2, INPUT); + pinMode(white, OUTPUT); + pinMode(green, OUTPUT); + pinMode(yellow, OUTPUT); + pinMode(orange, OUTPUT); + pinMode(red, OUTPUT); + digitalWrite(white, HIGH); + timer=analogRead(pot2); +} +int time=0; +void loop() +{ + if(time%100==0){ + digitalWrite(bz3,LOW); + digitalWrite(bz2,LOW); + digitalWrite(bz1,LOW); + int fre=analogRead(pot1); + if(fre<=341){ + digitalWrite(bz1,HIGH); + } + else if(fre<=682){ + digitalWrite(bz2,HIGH); + } + else{ + digitalWrite(bz3,HIGH); + } + } + if(timer==0){ + timer=analogRead(pot2); + digitalWrite(led+8,LOW); + led=(led+1)%5; + digitalWrite(led+8,HIGH); + } + time++; + timer--; + if(time>10000)time-=10000; + delay(1); +} +//https://www.tinkercad.com/things/f5dLJcZCVPw/editel?returnTo=%2Fdashboard \ No newline at end of file