Skip to content

Instantly share code, notes, and snippets.

@AliBasicCoder
Last active March 6, 2024 14:33
Show Gist options
  • Select an option

  • Save AliBasicCoder/843faf94d2dc301a544a6f84bff4c303 to your computer and use it in GitHub Desktop.

Select an option

Save AliBasicCoder/843faf94d2dc301a544a6f84bff4c303 to your computer and use it in GitHub Desktop.
#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