-4

I have the following formula:

ciphertext[i] =  ((plaintext[i] -'a' + k) % 26)  + 'a';

I'm trying to solve for plaintext[i] given ciphertext[i].

I'm using a vigenere cipher. If I convert plain text to cipher text shouldn't there be a way to convert the cipher text back to plain text?

Here's the entire code:

#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>



int main(int argc, string argv[]){

if (argc !=2){
    printf("FATAL ERROR: All hail Caesar!");
    return 1;
}

for(int i = 0, n=strlen(argv[1]);i < n;i++){
    if(!isupper(argv[1][i]) && !islower(argv[1][i])){
       printf("FATAL ERROR: All hail Mark Anthony!");
       return 1;
    }
}

int cipherlength = strlen(argv[1]),ciphercount=0;
char cipherkey[strlen(argv[1])];
for(int i = 0, n=strlen(argv[1]);i < n;i++){
    cipherkey[i] = argv[1][i];
}

string plaintext = NULL;
int k;

do{
   printf("plaintext:  ");
   plaintext = get_string();
   printf("ciphertext: ");
}while(plaintext == NULL);



char ciphertext[strlen(plaintext)];
char xiphertext[strlen(plaintext)];

k = atoi(argv[1]);

for (int i = 0,n=strlen(plaintext);i < n; i++){

    int index = ciphercount % cipherlength;

    if(isupper(cipherkey[index])) k = cipherkey[index] - 'A';
    else if(islower(cipherkey[index])) k = cipherkey[index] - 'a';

    if      ((int)plaintext[i] >= 65 && (int)plaintext[i] <= 90){
       ciphertext[i] =  ((plaintext[i] -'A' + k) % 26)  + 'A';
       xiphertext[i] =  ((plaintext[i] -'A' - k) % 26)  + 'A';
       ciphercount++;
    }else if ((int)plaintext[i] >= 97 && (int)plaintext[i] <= 122){
       ciphertext[i] =  ((plaintext[i] -'a' + k) % 26)  + 'a';
       xiphertext[i] =  ((plaintext[i] -'a' - k) % 26)  + 'a';
       ciphercount++;
    }else {
        ciphertext[i] = plaintext[i];
        xiphertext[i] = plaintext[i];
    }
    printf("%c %c %c /n",plaintext[i],ciphertext[i],xiphertext[i]);
}
printf("\n");

}

When I enter abcdefghijklmnopqrstuvwxyz using random as the key word I get:

rbpgsrxhvmyxdnbsedjthykjpz as ciphertext[]

but when I enter rbpgsrxhvmyxdnbsedjthykjpz again using random as the key word I get:

abcdefghijklSnUpWXYt[v]^_z  as xiphertext[]

so it works up to the letter m

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
DCR
  • 14,737
  • 12
  • 52
  • 115

1 Answers1

3

You wouldn't be able to solve it, because % 26 operation produces the same values for different plaintext[i]s. You can produce one possible plaintext of a great number of possibilities by computing

plaintext[i] = ((ciphertext[i]-'a'- k) % 26) + 'a';

Demo.

thanks, I needed to add the following:

 if ((plaintext[i] - 'a' - k)%26 < 0)xiphertext[i] = ((plaintext[i] -'a' - k + 26) % 26)  + 'a';
DCR
  • 14,737
  • 12
  • 52
  • 115
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • I'm using a vigenere cipher. If I convert plain text to cipher text shouldn't there be a way to convert the cipher text back to plain text? – DCR Jul 23 '17 at 22:08
  • @DCR `% 26` will produce the same value for `'a'` and for `'{'`. You can't restore the original value unless you ensure that all input consists of, for example, alphabetical characters. – Sergey Kalinichenko Jul 23 '17 at 22:13
  • so I added the code and they are all alpha but the reverse isn't working – DCR Jul 23 '17 at 22:22
  • @DCR Take a look at my demo link, it gets the result reversed correctly. For larger values of `k` you may need to add `26` to the result of `ciphertext[i]-'a'- k`, i.e. `ciphertext[i]-'a'- k+26` or even `ciphertext[i]-'a'- k+52`. – Sergey Kalinichenko Jul 23 '17 at 22:30
  • Vigenere cipher only encodes alphabetic characters. So if an encoding produces the same value for `a` and `{`, you decode it to `a`. – Barmar Jul 23 '17 at 22:36