diff --git a/Affinecipher.cpp b/Affinecipher.cpp new file mode 100644 index 0000000..8ab7cf3 --- /dev/null +++ b/Affinecipher.cpp @@ -0,0 +1,108 @@ +#include +#include +#include +using namespace std; + +int gcd(int a, int b) { + if (b == 0) + return a; + return gcd(b, a % b); +} + +int inverse(int a, int m) { + a = a % m; + for (int x = 1; x < m; x++) { + if ((a * x) % m == 1) + return x; + } + return -1; +} + +string affineEncrypt(string text, int a, int b) { + string result = ""; + + for (int i = 0; i < text.length(); i++) { + + if (isalpha(text[i])) { + char offset; + if (isupper(text[i])) { + offset = 'A'; + } else { + offset = 'a'; + } + + int x = text[i] - offset; + int encrypted = (a * x + b) % 26; + char newChar = char(encrypted + offset); + result += newChar; + } else { + result += text[i]; //only alphabet encruption + } + } + + return result; +} + +// Decrypt using Affine Cipher +string affineDecrypt(string text, int a, int b) { + int a_inv = inverse(a, 26); + // if (a_inv == -1) { + // return "Invalid key: 'a' has no modular inverse."; + // } + + string result = ""; + + for (int i = 0; i < text.length(); i++) { + + if (isalpha(text[i])) { + char offset; + if (isupper(text[i])) { + offset = 'A'; + } else { + offset = 'a'; + } + + int y = text[i] - offset; + int decrypted = (a_inv * (y - b + 26)) % 26;//add 26 to prevent negative values -1+'65' + char newChar = char(decrypted + offset); + result += newChar; + } else { + result += text[i]; + } + } + + return result; +} + +int main() { + string input; + int a, b; + char choice; + + cout << "Enter text: "; + getline(cin, input); + cout << "Enter \"a\" (coprime with 26): "; + cin >> a; + if (gcd(a, 26) != 1) { + cout << "Invalid key: 'a' must be coprime with 26.\n"; + return 1; + } + cout << "Enter \"b\": "; + cin >> b; + cout << "Encrypt (e) or Decrypt (d)? "; + cin >> choice; + + cin.ignore(); // Clear newline left in buffer + + if (choice == 'e') { + string encrypted = affineEncrypt(input, a, b); + cout << "Encrypted Text: " << encrypted << endl; + } else if (choice == 'd') { + string decrypted = affineDecrypt(input, a, b); + cout << "Decrypted Text: " << decrypted << endl; + } else { + cout << "Invalid choice.\n"; + } + + return 0; +} diff --git a/Assignments/Assignment0/ManantSinghal_240615/.DS_Store b/Assignments/Assignment0/ManantSinghal_240615/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/Assignments/Assignment0/ManantSinghal_240615/.DS_Store differ diff --git a/Assignments/Assignment0/ManantSinghal_240615/Enigma.js b/Assignments/Assignment0/ManantSinghal_240615/Enigma.js new file mode 100644 index 0000000..1185f2e --- /dev/null +++ b/Assignments/Assignment0/ManantSinghal_240615/Enigma.js @@ -0,0 +1,237 @@ +import "graphics"; +import "EnigmaConstants.js"; + +function Enigma() { + var enigmaImage = GImage("EnigmaTopView.png"); + var gw = GWindow(enigmaImage.getWidth(), enigmaImage.getHeight()); + gw.add(enigmaImage); + runEnigmaSimulation(gw); +} + +function runEnigmaSimulation(gw) { + var enigma = { + KEYS: [], + lamps: [], + rotors: [] + }; + + // Add KEYS and lamps + for (var i = 0; i < 26; i++) { + var ch = String.fromCharCode("A".charCodeAt(0) + i); + var center = KEY_LOCATIONS[i]; + var key = createKey(ch); + key.setLocation(center.x - KEY_RADIUS, center.y - KEY_RADIUS); + gw.add(key); + enigma.KEYS.push(key); + + var center2 = LAMP_LOCATIONS[i]; + var lamp = createLamp(ch); + lamp.setLocation(center2.x - LAMP_RADIUS, center2.y - LAMP_RADIUS); + gw.add(lamp); + enigma.lamps.push(lamp); + } + + // Add rotors + for (var i = 0; i < 3; i++) { + var loc = ROTOR_LOCATIONS[i]; + var rotor = createRotor("A"); + rotor.setLocation(loc.x - ROTOR_WIDTH / 2, loc.y - ROTOR_HEIGHT / 2); + gw.add(rotor); + enigma.rotors.push(rotor); + } + + // Mouse event listeners + gw.addEventListener("mousedown", function (e) { + var obj = gw.getElementAt(e.getX(), e.getY()); + if (obj !== null && obj.mousedownAction !== undefined) { + obj.mousedownAction(enigma); + } + }); + + gw.addEventListener("mouseup", function (e) { + var obj = gw.getElementAt(e.getX(), e.getY()); + if (obj !== null && obj.mouseupAction !== undefined) { + obj.mouseupAction(enigma); + } + }); +} + +function createKey(letter) { + var key = GCompound(); + var border = GOval(0, 0, 2 * KEY_RADIUS, 2 * KEY_RADIUS); + border.setFilled(true); + border.setFillColor(KEY_BORDER_COLOR); + key.add(border); + + var inner = GOval(KEY_BORDER, KEY_BORDER, + 2 * (KEY_RADIUS - KEY_BORDER), + 2 * (KEY_RADIUS - KEY_BORDER)); + inner.setFilled(true); + inner.setFillColor(KEY_BGCOLOR); + key.add(inner); + + var label = GLabel(letter); + label.setFont(KEY_FONT); + label.setColor(KEY_UP_COLOR); + label.setLocation(KEY_RADIUS - label.getWidth() / 2, + KEY_RADIUS + KEY_LABEL_DY); + key.add(label); + + key.mousedownAction = function(enigma) { + label.setColor(KEY_DOWN_COLOR);//milestone 2 + advance_rotors(enigma);//milestone 9 + var first = forward(letter, enigma); + var second = reflector(first); + var third = backward(second, enigma); + lamp_on(third, enigma); +}; + + key.mouseupAction = function (enigma) { + label.setColor(KEY_UP_COLOR); + // Turn off all lamps on key release + for (var i = 0; i < enigma.lamps.length; i++) { + enigma.lamps[i].label.setColor(LAMP_OFF_COLOR); + } + }; + + return key; +} +//MILESTONE 3 +function createLamp(letter) { + var lamp = GCompound(); + + var border = GOval(0, 0, 2 * LAMP_RADIUS, 2 * LAMP_RADIUS); + border.setFilled(true); + border.setFillColor(LAMP_BORDER_COLOR); + lamp.add(border); + + var label = GLabel(letter); + label.setFont(LAMP_FONT); + label.setColor(LAMP_OFF_COLOR); + label.setLocation(LAMP_RADIUS - label.getWidth() / 2, + LAMP_RADIUS + LAMP_LABEL_DY); + lamp.add(label); + + lamp.label = label; // Attach label so you can change color later + + return lamp; +} +//MILESTONE 5 +function createRotor(letter) { + var rotor = GCompound(); + + var border = GRect(0, 0, ROTOR_WIDTH, ROTOR_HEIGHT); + border.setFilled(true); + border.setFillColor(ROTOR_BGCOLOR); + rotor.add(border); + + var label = GLabel(letter); + label.setFont(ROTOR_FONT); + label.setColor(ROTOR_COLOR); + label.setLocation((ROTOR_WIDTH - label.getWidth()) / 2, + ROTOR_HEIGHT - ROTOR_LABEL_DY+5);//manual positioning + rotor.add(label); + + rotor.label = label; + + //MILESTONE 6(Clickaction) + rotor.mouseupAction = function (enigma) {//only mouseup action needed for rotor part + var current = rotor.label.getLabel(); + var next = String.fromCharCode((current.charCodeAt(0) - 65 + 1) % 26 + 65); + rotor.label.setLabel(next); + }; + + return rotor; +} + +// Basic single rotor encryption function + +function reflector(letter) { + var index = letter.charCodeAt(0) - "A".charCodeAt(0); + return REFLECTOR_PERMUTATION.charAt(index); +} + +function forward(letter, enigma) { + var index = letter.charCodeAt(0) - "A".charCodeAt(0); + var mappedChar = ""; + var mappedIndex = 0; + + for (var i = 2; i >= 0; i--) { + var rotor = ROTOR_PERMUTATIONS[i]; + + // Get the rotor offset from the label + var rotorLetter = enigma.rotors[i].label.getLabel(); + var offset = rotorLetter.charCodeAt(0) - "A".charCodeAt(0); + + var shiftedIndex = (index + offset) % 26;//DOUBT>>rotor.charAt(index+offset))-"A".charCodeAt(offset) + mappedChar = rotor.charAt(shiftedIndex); + index = (mappedChar.charCodeAt(0) - "A".charCodeAt(0) - offset + 26) % 26; + } + mappedIndex = index; + return String.fromCharCode(index + "A".charCodeAt(0)); +} +// use .indexOf method to find the index which would have been created into the letter during backward encryption (inverse permutations) +//Milestone 7 +function backward(letter, enigma) { + var index = letter.charCodeAt(0) - "A".charCodeAt(0); + + for (var i = 0; i < 3; i++) { + var rotor = ROTOR_PERMUTATIONS[i]; + var rotorLetter = enigma.rotors[i].label.getLabel(); + var offset = rotorLetter.charCodeAt(0) - "A".charCodeAt(0); + + // Adjust for offset before finding inverse mapping + var shiftedIndex = (index + offset) % 26; + var shiftedChar = String.fromCharCode(shiftedIndex + 65); + + // Inverse lookup: find position where rotor maps to shiftedChar + var inverseIndex = rotor.indexOf(shiftedChar); + + // Undo the offset + index = (inverseIndex - offset + 26) % 26; + } + return String.fromCharCode(index + 65); +} + +//MILESTONE 4 +function lamp_on(letter, enigma) { + var index = letter.charCodeAt(0) - "A".charCodeAt(0); + var lamp = enigma.lamps[index]; + + if (lamp !== undefined && lamp !== null) { + var label = lamp.label; + if (label !== undefined && label !== null) { + label.setColor(LAMP_ON_COLOR); + } + } + else { + println("Lamp is missing at index " + index); + } +} + +//MILESTONE 9 +function advance_rotors(enigma) { + var r2 = enigma.rotors[2]; // fast + var r1 = enigma.rotors[1]; // medium + var r0 = enigma.rotors[0]; // slow + + // Advance fast rotor + var fastLetter = r2.label.getLabel(); + var fastNext = String.fromCharCode((fastLetter.charCodeAt(0) - 65 + 1) % 26 + 65); + r2.label.setLabel(fastNext); + + // If fast rotor wraps from Z → A, step middle + if (fastLetter === "Z") { + var midLetter = r1.label.getLabel(); + var midNext = String.fromCharCode((midLetter.charCodeAt(0) - 65 + 1) % 26 + 65); + r1.label.setLabel(midNext); + + // If middle wraps, step slow + if (midLetter === "Z") { + var slowLetter = r0.label.getLabel(); + var slowNext = String.fromCharCode((slowLetter.charCodeAt(0) - 65 + 1) % 26 + 65); + r0.label.setLabel(slowNext); + } + } +} + diff --git a/Assignments/Assignment0/ManantSinghal_240615/EnigmaConstants.js b/Assignments/Assignment0/ManantSinghal_240615/EnigmaConstants.js new file mode 100644 index 0000000..7064b8d --- /dev/null +++ b/Assignments/Assignment0/ManantSinghal_240615/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/Assignments/Assignment0/ManantSinghal_240615/EnigmaTopView.png b/Assignments/Assignment0/ManantSinghal_240615/EnigmaTopView.png new file mode 100644 index 0000000..2c40808 Binary files /dev/null and b/Assignments/Assignment0/ManantSinghal_240615/EnigmaTopView.png differ diff --git a/Assignments/Assignment0/ManantSinghal_240615/SJS.jar b/Assignments/Assignment0/ManantSinghal_240615/SJS.jar new file mode 100644 index 0000000..79bd637 Binary files /dev/null and b/Assignments/Assignment0/ManantSinghal_240615/SJS.jar differ diff --git a/Tinkercad_task_240615/Tinkercad_task_240615.ino b/Tinkercad_task_240615/Tinkercad_task_240615.ino new file mode 100644 index 0000000..753d6f9 --- /dev/null +++ b/Tinkercad_task_240615/Tinkercad_task_240615.ino @@ -0,0 +1,55 @@ +int pot1Pin = A0; +int pot2Pin = A1; + +int buzzer1 = 2; +int buzzer2 = 3; +int buzzer3 = 4; + +int leds[5] = {5, 6, 7, 8, 9}; + +void setup() { + pinMode(buzzer1, OUTPUT); + pinMode(buzzer2, OUTPUT); + pinMode(buzzer3, OUTPUT); + + for (int i = 0; i < 5; i++) { + pinMode(leds[i], OUTPUT); + } + + Serial.begin(9600); +} + +void loop() { + int pot1Value = analogRead(pot1Pin); + int pot2Value = analogRead(pot2Pin); + + Serial.print("POT.1 (Buzzer): "); + Serial.print(pot1Value); + if (pot1Value <= 341) { + Serial.println("Buzzer 1"); + } else if (pot1Value <= 682) { + Serial.println("Buzzer 2"); + } else { + Serial.println("Buzzer 3"); + } + + digitalWrite(buzzer1, pot1Value <= 341 ? HIGH : LOW); + digitalWrite(buzzer2, (pot1Value > 341 && pot1Value <= 682) ? HIGH : LOW); + digitalWrite(buzzer3, pot1Value > 682 ? HIGH : LOW); + + Serial.print("POT2 (LED): "); + Serial.print(pot2Value); + + int delayTime = map(pot2Value, 0, 1023, 100, 1000); + Serial.print(delayTime); + Serial.println(" ms delay"); + + + for (int i = 0; i < 5; i++) { + for (int j = 0; j < 5; j++) { + digitalWrite(leds[j], j == i ? HIGH : LOW); + } + delay(delayTime); + } +} +//LINk https://www.tinkercad.com/things/6vFHFkAIlQt-mighty-blad diff --git a/logic.c b/logic.c new file mode 100644 index 0000000..271b782 --- /dev/null +++ b/logic.c @@ -0,0 +1,260 @@ +#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 +}; + +char reflector[ALPHABET_SIZE + 1] = "YRUHQSLDPXNGOKMIEBFZCWVJAT"; + +volatile int rotor_offsets[NUM_ROTORS] = {0, 0, 0}; // Right, middle, left +int turnovers[NUM_ROTORS] = {'Q' - 'A', 'E' - 'A', 'V' - 'A'}; +int pairings[ALPHABET_SIZE] = {0}; +char input_buffer[256] = {0}; +char output_buffer[256] = {0}; +int stepping[NUM_ROTORS] = {0, 0, 0}; + +int char_to_index(char c) { + return toupper(c) - 'A'; +} + +char index_to_char(int index) { + return 'A' + (index % ALPHABET_SIZE); +} + +int index_inverse(int c, int rotor) { + 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; + } + } + } +} + +// Swap a letter through the plugboard +int plug_swap(int input) { + // Add the offset (which may be 0 if no swap) to the input + return input + pairings[input]; +} + +void spin_rotors() { + for (int i = 0; i < NUM_ROTORS; i++) { + stepping[i] = 0; + } + for (int i = NUM_ROTORS - 1; i > 0; i--) { + if (rotor_offsets[i-1] == turnovers[i-1]) { + rotor_offsets[i] = (rotor_offsets[i] + 1) % ALPHABET_SIZE; + stepping[i] = 1; + } + } + rotor_offsets[0] = (rotor_offsets[0] + 1) % ALPHABET_SIZE; + if(stepping[2]==1 && stepping[1]==0) + rotor_offsets[1]=(rotor_offsets[1]+1)%26; +} + +// Simple encrypt character function (without threading) +char encrypt_char(char c) { + // If not a letter, return unchanged + 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') { + if (input[i] == ' ') { + // When space is encountered, prompt for plugboard change + printf("\nSpace detected. Do you want to change plugboard configuration? (y/n): "); + char response; + scanf(" %c", &response); + getchar(); // Clear the newline + + if (tolower(response) == 'y') { + char new_pairs[256]; + printf("Enter new plugboard pairs (e.g., 'A B C D' to swap A-B and C-D): "); + fgets(new_pairs, sizeof(new_pairs), stdin); + new_pairs[strcspn(new_pairs, "\n")] = '\0'; // Remove newline + initialize_plugboard(new_pairs); + printf("Plugboard configuration updated.\n"); + } + + // Add the space to output + output[i] = ' '; + i++; + continue; + } + + 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] = ""; + + 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: 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); + plugboard_config[strcspn(plugboard_config, "\n")] = '\0'; // Remove newline + 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("Exiting Enigma simulator.\n"); + break; + } + else { + printf("Invalid command. Please try again.\n\n"); + } + } + + return 0; +} \ No newline at end of file