0

I am working on a Caesar function, which given the input and the offset, returns the output. I'm not sure if I am doing it. What am I doing wrong here? Any help is appreciated. Also if someone could explain me how to work with unsigned chars.

void encrypt(unsigned char* message_input, char off, unsigned char* message_output) {

    int m_inp;

    while(*(message_input+ m_inp)!=EOF)
    {
        *(message_output+ m_inp) = (*((unsigned char*)input + m_inp) + offset )%256;
    }

}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • `EOF` is of type `int` and has a negative value. All values of objects of type `unsigned char` are positive. Your comparison will always be *true* (for ever and ever and ever ...). – pmg Mar 03 '13 at 19:44
  • without initializing m_inp , you can't dereference (message_output + m_inp) – Barath Ravikumar Mar 03 '13 at 19:50
  • just means , i am trying to achieve this using unsigned char, not signed chars or just chars. –  Mar 03 '13 at 20:12

2 Answers2

1

There are a number of correctness and stylistic issues with the code.

Correctness issues

  1. The loop variable, m_inp, is not initialized.

  2. It is unlikely that an unsigned char can ever equal EOF. The value of EOF is -1. The loop will never finish (unless you are on a very strange architecture).

  3. The traditional Caesar cipher operates alphabetically, rather than on the whole ASCII character set.

Stylistic issues

Using more "stylistically correct" C will make it easier for other programmers to read your code. These are subjective.

  1. The name m_inp is a poor name for a loop variable in a short loop. Use i instead.

  2. It is easier to read ptr[i] instead of *(ptr + i), even though they are exactly equivalent in C.

  3. Marking the input as const unsigned char * makes it more obvious that it is not modified.

  4. Use int instead of char for the offset.

  5. Traditionally, function outputs go on the left, inputs go on the right. This is not important, however.

Revised code

Here is a sample revision. It takes a NUL-terminated string, and writes the Caesar encoded / decoded version to an output buffer. This is how I would write the function, not necessarily how you would write it:

void caesar(char *output, const char *input, int shift)
{
    int i;
    for (i = 0; input[i]; i++) {
        if (input[i] >= 'a' && input[i] <= 'z')
            output[i] = (input[i] - 'a' + shift) % 26 + 'a';
        else if (input[i] >= 'A' && input[i] <= 'Z')
            output[i] = (input[i] - 'A' + shift) % 26 + 'A';
        else
            output[i] = input[i];
    }
    output[i] = '\0';
}

Note that Caesar encryption and decryption are actually the same operation, just with different shift values. So if you encrypt with a shift of 3, you can decrypt with a shift of -3 (or equivalently, 23).

Also note that you can replace unsigned char with char or vice versa and everything will work exactly the same (although you'd need to cast the inputs).

Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
0

The code you have written has a lot of mistakes

1) You have not initialized m_inp , but you are deferencing (message_output + m_inp)

2) You are checking the input string for EOF , which makes no sense.

Please have a look at this code , it is a much better implementation of caesar cipher

#include <stdio.h>

void caesar (char cipher[], int shift);

int main () {

char cipher[50];
int shift;

printf("Enter text to be encrypted IN CAPITAL LETTERS ONLY: ");
scanf("%s", cipher);

printf("How many shifts do you prefer? 1-10 only: ");
scanf("%d", &shift);

caesar (cipher, shift);

return 0;
}

void caesar (char cipher[], int shift) {
  int i = 0;

  while (cipher[i] != '\0') {
    if ((cipher[i] += shift) >= 65 && (cipher[i] + shift) <= 90) {
      cipher[i] += (shift);
     } else {
      cipher[i] += (shift - 25); 
       }
    i++;
   }
  printf("%s", cipher);
}
Barath Ravikumar
  • 5,658
  • 3
  • 23
  • 39
  • 3
    I don't see a string literal. – Dietrich Epp Mar 03 '13 at 20:01
  • @DietrichEpp I mean the non mutable char * message_input and char * message_output strings – Barath Ravikumar Mar 03 '13 at 20:05
  • @ i made the changes above. Does that look rite? –  Mar 03 '13 at 20:08
  • What makes them immutable? – Dietrich Epp Mar 03 '13 at 20:09
  • @DietrichEpp , I thought i learnt that the string created is constant , and modifying them is undefined , but cannot recall where , please help me out if you can . But i have found out that it is depreciated in c++ http://stackoverflow.com/questions/8126512/deprecated-conversion-from-string-constant-to-char – Barath Ravikumar Mar 03 '13 at 20:17
  • @DietrichEpp I have read the part where you cant change char * "str" , in page 73 of a book called "head first C" . The book goes on to say that "str" , gets stored in constant [read only] section of data memory. If there is any mistake in my understanding please do correct me. – Barath Ravikumar Mar 03 '13 at 20:30
  • @BarathBushan: A string literal like `"str"` should not be modified, you are correct about that. However, if you look at the code in the question, there are no string literals anywhere. – Dietrich Epp Mar 03 '13 at 21:37
  • @DietrichEpp Sorry for wasting your time , i made a wrong assumption , that the user would pass the string itself as i/p parameter while calling the encrypt function. – Barath Ravikumar Mar 04 '13 at 01:52
  • It's not a waste of time, that's what the site is here for. – Dietrich Epp Mar 04 '13 at 08:05