Skip to main content
Code Review

Return to Question

replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link

I am using the modInverse() function from Rosetta Code. This is quasi-related to my ongoing series of classical ciphers. So far I have done a simple Caesar cipher simple Caesar cipher and an Atbash cipher.

I am using the modInverse() function from Rosetta Code. This is quasi-related to my ongoing series of classical ciphers. So far I have done a simple Caesar cipher and an Atbash cipher.

I am using the modInverse() function from Rosetta Code. This is quasi-related to my ongoing series of classical ciphers. So far I have done a simple Caesar cipher and an Atbash cipher.

Tweeted twitter.com/StackCodeReview/status/820486821222248449
edited tags
Link
200_success
  • 145.6k
  • 22
  • 190
  • 479
Source Link
esote
  • 3.8k
  • 2
  • 25
  • 44

Simple Affine cipher

The affine cipher is a simple mathematical substitution cipher. If you're interested in the details behind how it works, this page goes further into detail.

After writing a program to encrypt and decrypt text using the affine cipher, I felt that it seemed needlessly cluttered. I have also noticed that there are no questions related to the affine cipher on Code Review, at least not for C++.

Here's the code:

#include <iostream>
#include <algorithm>
#include <numeric>
#include <cmath>
int gcd(int a, int b);
int modInverse(int a, int b); // from https://rosettacode.org/wiki/Modular_inverse#C.2B.2B
int main(){
 std::string choice;
 do{
 std::cout << "Encrypt or Decrypt? [e/d] = ";
 std::getline(std::cin, choice);
 std::transform(choice.begin(), choice.end(), choice.begin(), ::tolower);
 } while(choice.length() > 1 || choice != "e" && choice != "d");
 std::cout << "\nInput string: ";
 std::string input;
 std::getline(std::cin, input);
 int a, b;
 do{
 std::cout << "\na and b must be coprime\na = ";
 std::cin >> a;
 std::cout << "b = ";
 std::cin >> b;
 } while(std::cin.fail() || gcd(a,b) != 1);
 std::cout << '\n';
 if(choice == "e"){
 for(int i = 0; i < input.length(); ++i){
 if(input[i] >= 'a' && input[i] <= 'z'){
 std::cout << (char)((a * (input[i] - 'a') + b) % 26 + 'a');
 } else if(input[i] >= 'A' && input[i] <= 'Z'){
 std::cout << (char)((a * (input[i] - 'A') + b) % 26 + 'A');
 } else{
 std::cout << input[i];
 }
 }
 } else{
 for(int i = 0; i < input.length(); ++i){
 if(input[i] >= 'a' && input[i] <= 'z'){
 std::cout << (char)(modInverse(a, 26) * (26 + input[i] - 'a' - b) % 26 + 'a');
 } else if(input[i] >= 'A' && input[i] <= 'Z'){
 std::cout << (char)(modInverse(a, 26) * (26 + input[i] - 'A' - b) % 26 + 'A');
 } else{
 std::cout << input[i];
 }
 }
 }
 std::cout << '\n';
 return 0;
}
int gcd(int a, int b){
 return b == 0 ? a : gcd(b, a % b);
}
int modInverse(int a, int b){
 int b0 = b, t, q;
 int x0 = 0, x1 = 1;
 if (b == 1) return 1;
 while (a > 1) {
 q = a / b;
 t = b, b = a % b, a = t;
 t = x0, x0 = x1 - q * x0, x1 = t;
 }
 if (x1 < 0) x1 += b0;
 return x1;
}

Here is an example output for the encryption side:

Encrypt or Decrypt? [e/d] = e
Input string: Hello World!
a and b must be coprime
a = 5
b = 9
Sdmmb Pbqmy!

And here is an example output for the decryption side:

Encrypt or Decrypt? [e/d] = d
Input string: Sdmmb Pbqmy!
a and b must be coprime
a = 5
b = 9
Hello World!

I am using the modInverse() function from Rosetta Code. This is quasi-related to my ongoing series of classical ciphers. So far I have done a simple Caesar cipher and an Atbash cipher.

How can I improve this code, both for readability and for efficiency?

lang-cpp

AltStyle によって変換されたページ (->オリジナル) /