2

I am attempting to make the vigenere cipher. Information about it is here: https://www.youtube.com/watch?v=9zASwVoshiM My code doesnt seem to work for a few cases. My code is listed below please dont send me a link how to make the vigenere cipher but instead a way to fix mine. If I put the key as z for example it is value 25 acc to alphabet. Now if I put the to be encrypted text as c which is 2 the new text is of value 27 and should show b but for me it doesn't. So if the value exceeds 25 it doesn't show what I want else it works. And for the actual output example: ab as key should change ca to cb

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

    int main( int argc , string argv[]){
        //string plaintext;

        string key;
        if(argc != 2){
            printf("Please run the programme again this time using a command line argument!\n");
            return 1;
        }
        key = argv[1];
        int keys[strlen(key)];


        for(int m = 0; m< strlen(key);m++){
            if(isalpha(key[m])==false){
                printf("Re-Run The programme without any symbols.\n");
                return 1;
            }
        }

        for(int b = 0; b < strlen(key);b++){
            if(isupper(key[b]) == false){
                keys[b] = key[b] - 'a';
            }
            else{
                keys[b] = key[b] - 'A';
            }
        }

        //printf("Enter a string which should be encrypted: \n");
        string plaintext = GetString();
        int plength = strlen(plaintext);
        int klength = strlen(key);
        string ciphertext = key;

        for(int u = 0; u<plength;u++){
            if(isalpha(plaintext[u])==false){
                printf("%c",plaintext[u]);
                continue;
            }
            int value = u % klength;

            ciphertext[u] = (keys[value] + plaintext[u]);
            //By the more than 90 I am referring to 'z'
if(ciphertext[u]>90){
                ciphertext[u] = ciphertext[u] ;
            }

            printf("%c",ciphertext[u]);
        }

        printf("\n");
        return 0;
    }

Thanks Kalyan

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Kalyan Nadimpalli
  • 319
  • 1
  • 2
  • 10
  • 2
    Your formatting/indentation needs attention. – Martin James Nov 28 '15 at 06:34
  • You need to show us some input, the expected output, and the actual output. There are a large number of other questions about Vigenere ciphers here on SO — some of them listed in the 'related' questions section on the right of the page — and the chances are high that one of them will explain what your problem is. (Your line `if(ciphertext[u]>90){` should not be using `90`; presumably you're referring to `'Z'`.) – Jonathan Leffler Nov 28 '15 at 07:14
  • Note that the character code for lower-case letter z is 122 in ASCII and related code sets (such as CP 1252, 8859-1, 8859-15 and Unicode); upper-case letter Z is 90. Please update the question with the extra information such as a key that causes trouble, the sample input data, the actual output data (we should not have to compile your code to find out what you see, not least because we may not see what you see as we have different computers) and the desired output data. Then delete the comments you've made so far. When it's your question, clarifications go in the question, not in comments. – Jonathan Leffler Nov 28 '15 at 07:39
  • For key = `abc` and text = `dog`, the actual output = `dpi` instead of the expected output = `eqj`. There's an off-by-one error — I'm not sure if it is in your expectations or in the code. If key `a` should shift by 1, then key `z` should be the no-op shift by 26 — correct? Anyway, fixing an off-by-one error is usually rather straight-forward. Unfortunately, it's quite a bit more convoluted here: you have `if (ciphertext[u] > 90) { ciphertext[u] = ciphertext[u]; }` which doesn't change anything. Note that all the letters in `dog` have a value `> 90`. Handle lower and upper case separately. – Jonathan Leffler Nov 28 '15 at 07:59
  • Jonathan the off by one is all acc to plan and the >90 I didn't know what to do, please provide code to fix the vigenere cipher – Kalyan Nadimpalli Nov 28 '15 at 08:43

1 Answers1

1

You are correctly processing the value in the key by consistently substracting from its code the code of 'A' for an uppercase letter and 'a' for a lower case one. It gives you: A|a => 0, B|b => 1, ... , Z|z => 25. Fine till here...

But when encrypting, you are just adding this value to the code of a character without wrapping at any time.

Let us use your example: key is 'z' => value 25 in keys, fine. Take character 'c'. Its ASCII(*) code is 0x63 or 99. 99+25=124 giving in ascii table '|' ! To correctly wrap it, you must ensure that in any way 'z' + 1 => 'a'. You code could be

        /* test wrapping for lowercase letters */
        if ((islower(plaintext[u]) && (ciphertext[u]>'z')) {
            ciphertext[u] = ciphertext[u] - 'z' + 'a'  - 1;
        }
        /* same for uppercase */
        if ((isupper(plaintext[u]) && (ciphertext[u]>'Z')) {
            ciphertext[u] = ciphertext[u] - 'Z' + 'A'  - 1;
        }

(*) the example assumed ASCII code because it is the most common nowadays, but the code only assumes that all uppercase letters are in sequence and all lowercase letters are also in sequence without any requirement for their exact values nor the order of upper and lower case sequences.

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252