Last active
March 6, 2024 14:33
-
-
Save AliBasicCoder/843faf94d2dc301a544a6f84bff4c303 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <iostream> | |
| #include <string> | |
| using namespace std; | |
| // a function to get a number input from user | |
| // message: a message to show to user | |
| // def: a default value for number | |
| // a: if a > 0, this means that we're current asking for parameter c | |
| // which we need to verify that a*c % 26 == 0, | |
| // if a == 0, means that we're not asking for parameter c so no extra verifications are needed | |
| int getValidInput(const char *message, int def, int a = 0) { | |
| // print message to user | |
| cout << message; | |
| // a variable to store the result | |
| int result; | |
| // keep asking user until he gives valid input | |
| while (true) { | |
| // string to store user input | |
| string text; | |
| // clear any errors in cin | |
| cin.clear(); | |
| // get user input and store it in text | |
| getline(cin, text); | |
| // if text is empty (user pressed enter with no input) | |
| if (text.empty()) { | |
| // if asking for parameter c, check that a*c % 26 == 1 | |
| // if it's not ask the user for input again | |
| if (a != 0 && a * def % 26 != 1) { | |
| cout << "a * c mod 26 must be 1! please try again: "; | |
| continue; | |
| } | |
| // return default value | |
| return def; | |
| } | |
| try { | |
| // convert text to integer, and store it in result | |
| result = stoi(text); | |
| } catch (...) { | |
| // if the text is not an inger ask the user for input again | |
| cout << "Invalid input! please try again: "; | |
| continue; | |
| } | |
| // if the input is less that or equal to 0, re-ask the user for input | |
| if (result <= 0) { | |
| cout << "Value must be bigger than 0! please try again: "; | |
| continue; | |
| } | |
| // if asking for parameter c, check that a*c % 26 == 1 | |
| if (a != 0 && a * result % 26 != 1) { | |
| // if it's not ask the user for input again | |
| cout << "a * c mod 26 must be 1! please try again: "; | |
| continue; | |
| } | |
| // if this line is reached the user entered a valid input | |
| // so break the loop (stop asking for input) | |
| break; | |
| } | |
| // return the result | |
| return result; | |
| } | |
| // function to cipher message using affine cipher | |
| // message: message from user | |
| void affineCipher() { | |
| string message; | |
| cout << "please enter your message: "; | |
| getline(cin, message); | |
| // get parameter a | |
| int a = getValidInput("please enter parameter a (press enter for default value of 5): ", 5); | |
| // get parameter b | |
| int b = getValidInput("please enter parameter b (press enter for default value of 8): ", 8); | |
| // get parameter c | |
| int c = getValidInput("please enter parameter c (press enter for default value of 21): ", 21, a); | |
| // loop through the message | |
| for (int i = 0; i < message.length(); i++) { | |
| // get the current character | |
| const char character = message[i]; | |
| // character is stored in ASCII encoding, where each character is resented with a number | |
| // in ASCII the uppercase A is represented by 65, b by 66 and so on... until z by 90 | |
| // we check if the character is between A and Z | |
| if (character >= 65 && character <= 90) { | |
| // the formula for affine cipher is | |
| // E(x) = ax + b mod 26. where x is the numeric value of the letter (it's order in the alphabet stating with A at 0) | |
| // so (character - 65) gets the numeric value of the character | |
| // and ((a * (character - 65) + b) % 26) get the numeric value of the ciphered character | |
| // and ... + 65 converts the numeric value back to the ASCII value | |
| // and char(...) convert the ASCII codepoint to the actual character | |
| cout << char(((a * (character - 65) + b) % 26) + 65); | |
| continue; | |
| } | |
| // similarly, in ASCII the lowercase a is represented by 97, b by 98 and so on until z by 122 | |
| // we check if the character is between a and z | |
| if (character >= 97 && character <= 122) { | |
| // the logic is exactly the same as before expect we need to use 97 instead of 65 | |
| // to convert the numeric value to the ASCII codepoint (since a is 97) | |
| cout << char(((a * (character - 97) + b) % 26) + 97); | |
| continue; | |
| } | |
| // if the character is not a letter print it as is. | |
| cout << character; | |
| } | |
| } | |
| void affineDecipher() { | |
| string message; | |
| cout << "please enter the ciphered message: "; | |
| getline(cin, message); | |
| int a = getValidInput("please enter parameter a (press enter for default value of 5): ", 5); | |
| int b = getValidInput("please enter parameter b (press enter for default value of 8): ", 8); | |
| int c = getValidInput("please enter parameter c (press enter for default value of 21): ", 21, a); | |
| for (int i = 0; i < message.length(); i++) { | |
| const char character = message[i]; | |
| if (character >= 65 && character <= 90) { | |
| // the formula for deciphering messages ciphered using affine cipher is | |
| // D(y) = c(y - b) where y is numeric value of the character | |
| // so (character - 65) gets the numeric value of the character | |
| // and (character - 65 - b) is (y - b) | |
| // we add b*26 because if character is smaller than 65 + b | |
| // this will make the expression ((c * (character - 65 - b + b * 26)) % 26) negative | |
| // which will cause the ASCII code point to be lower than 65 | |
| // which will make the new character not a letter | |
| // note that: since we are using modulo 26 adding any multiple of 26 | |
| // will not affect the result hence adding b*26 will only make sure the | |
| // expression value stays positive | |
| cout << char(((c * (character - 65 - b + b * 26)) % 26) + 65); | |
| continue; | |
| } | |
| if (character >= 97 && character <= 122) { | |
| cout << char(((c * (character - 97 - b + b * 26)) % 26) + 97); | |
| continue; | |
| } | |
| cout << character; | |
| } | |
| } | |
| int main() { | |
| affineCipher(); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment