0

I'm trying to implement the Vigenere Cipher, but I have a problem while trying to loop trough the key. First, all the little functions, although, I don't think the problem is there.

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

#define ALPHANUMERIC "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" /* all alphabetic characters at their corresponding indices */

char* squeeze(char[], int);
char* formatString(char[]);
int findindex(char c);

/* squeeze: remove all occurences of c in s */
char* squeeze(char s[], int c) 
{

    int i, j;

    for (i = j = 0; s[i] != '\0'; i++)
        if (s[i] != c)
            s[j++] = s[i];
    s[j] = '\0';
    // printf("%s\n", s);
    return s;
}

/*  formatString: remove all white spaces and special 
    characters and convert all letters to upper case */
char* formatString(char input[]) 
{
    int i;

    input = squeeze(input, ' ');

    for (i = 0; input[i] != '\0'; i++)
    {
        if (!isalnum(input[i]))
        {
            input = squeeze(input, input[i]);
            --i;
        }
        if (islower(input[i]))
            input[i] = toupper(input[i]);
    }
    // printf("%s\n", input);
    return input;
}

/* findindex: returns the predefined index of a given character */
int findindex(char c)
{
    int i;

    if (isdigit(c))
        return 26 + c - '0';

    for (i = 0; ALPHANUMERIC[i] != '\0'; i++)
        if (c == ALPHANUMERIC[i])
            return i;
    return -1;
}

And here is the cipher-function. Just to clarify, my idea was to loop through the text-string in the for-loop and use the j-counter to loop through the codeword by setting it to zero, when it reaches the end of the codeword. All the extra printf-s are for debugging purposes.

void cipher(char codeword[], char text[])
{
    int i, j;
    char newword[strlen(text)];
codeword = formatString(codeword);
text = formatString(text);

    printf("codeword = %s, text = %s\n", codeword, text );
    j = -1;
    for (i = 0; i < strlen(text); i++)
    {
        j++;

        printf("text[i] = %c, %d, codeword = %c, %d\n", text[i], findindex(text[i]), codeword[i], findindex(codeword[i]));

        newword[i] = ALPHANUMERIC[(findindex(text[i]) + findindex(codeword[j])) % 36];

        printf("i = %d, j = %d\n", i, j);

        if (j == strlen(codeword) - 1)
            j = -1;
    }

    printf("%s\n", newword);
}

So, looking at the code, it all seems fine, until i run it. That's the output with input "ivcho", "ivayloivayloo":

codeword = IVCHO, text = IVAYLOIVAYLOO
text[i] = I, 8, codeword = I, 8
i = 0, j = 0
text[i] = V, 21, codeword = V, 21
i = 1, j = 1
text[i] = A, 0, codeword = C, 2
i = 2, j = 2
text[i] = Y, 24, codeword = H, 7
i = 3, j = 3
text[i] = L, 11, codeword = O, 14
i = 4, j = 4
text[i] = O, 14, codeword = , -1
i = 5, j = 0
text[i] = I, 8, codeword = , -1
i = 6, j = 1
text[i] = V, 21, codeword = , -1
i = 7, j = 2
text[i] = A, 0, codeword = , -1
i = 8, j = 3
text[i] = Y, 24, codeword = G, 6
i = 9, j = 4
text[i] = L, 11, codeword = C, 2
i = 10, j = 0
text[i] = O, 14, codeword = C, 2
i = 11, j = 1
text[i] = O, 14, codeword = :, -1
i = 12, j = 2
QGC5ZW3XHCT9Q

When the counter (j) is set to zero, it just doesn't start over and I have no idea why.

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
smeshko
  • 1,184
  • 13
  • 27
  • 1
    your debug printf's aren't too healthy. You use the i variable to index characters in the codeword which is much smaller than the text. you're lucky not to get a SEGV – Ronald Jan 16 '14 at 13:32
  • 1
    I'm not sure what you mean, but it looks like you're indexing `codeword` with `[i]` on your long `printf` line (instead of, perhaps, `[j]`), and `i` increases beyond the length of your `codeword`. So at some point, that output produces a garbage (and indeed, that's what I seen in your output). –  Jan 16 '14 at 13:33
  • 1
    God, I'm an idiot... Yes, the program was correct, the printf's were not.. thanks for pointing it out ! – smeshko Jan 16 '14 at 13:36
  • You fail to make room for the string terminator. Change the declaration of newword: `char newword[strlen(text+1)];` – Klas Lindbäck Jan 16 '14 at 14:32

0 Answers0