XOR Encryption code produces wrong results

In the code blocks given below I am supposed to obtain an output like this:

  • Expected ciphertext: "'\r\u0006R\u0014\u0001\u001a\u0006\bR\a\u0006\u001c\u0012\rR\u0003\u001b\vE\t\a\b\u0004\0E\f\u0004\0\u0006S\u0011\v\u0017E\u0018\u0012\u001f\u001aR\u0001\u001b\u0014K"
  • Plain text: "The quick brown fox jumps over the lazy dog."
  • Secret: "secret"
  • My Output: 24 R

Original code address: https://www.programmingalgorithms.com/algorithm/xor-encryption/c/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/***********************************************/

char *XORCipher(char *data, char *key, int dataLen, int keyLen) {
  char *output = (char *)malloc(sizeof(char) * dataLen);

  for (int i = 0; i < dataLen; ++i) {
    output[i] = data[i] ^ key[i % keyLen];
  }

  return output;
}

int main(void) {

  char *text = "The quick brown fox jumps over the lazy dog.";
  char *key = "secret";
  int dataLen = strlen((char *)text);
  int keyLen = strlen((char *)key);

  char *cipherText = XORCipher(text, key, dataLen, keyLen);

  printf("%ld\n", strlen(cipherText));

  char *plainText = XORCipher(cipherText, key, dataLen, keyLen);
  printf("%s\n", cipherText);
  printf("%s\n", plainText);
}

1 answer

  • answered 2022-01-21 10:47 AKX

    So as said, there's nothing really wrong about your encryption code, you just can't print all of those bytes.

    Here's a slight rework that

    • moves the allocation outside the XORCipher function (so the caller is responsible for memory management)
    • adds an utility function to print byte values as well as the ASCII text
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    static void XORCipher(const char *data, const char *key, char *dest, int dataLen, int keyLen) {
      for (int i = 0; i < dataLen; ++i) {
        dest[i] = data[i] ^ key[i % keyLen];
      }
    }
    
    static void print_hex(const char *header, const unsigned char *data, int length) {
        int i = 0;
        while(i < length) {
            char asc_line[17] = {0};
            printf("%s(%04x): ", header, i);
            for(int j = 0; j < 16; i++, j++) {
                if(i < length) {
                    printf("%02x ", data[i]);
                    asc_line[j] = (data[i] >= 32 && data[i] <= 127 ? data[i] : '.');
                } else {
                    printf("   ");
                }
            }
            printf("| %-16s |\n", asc_line);
        }
        printf("%s\n----\n", data);
    }
    
    int main(void) {
    
      char *text = "The quick brown fox jumps over the lazy dog.";
      char *key = "secret";
      int dataLen = strlen((char *)text);
      int keyLen = strlen((char *)key);
      char *output = (char *)malloc(sizeof(char) * dataLen);
      print_hex("Original text", text, dataLen);
      XORCipher(text, key, output, dataLen, keyLen);
      print_hex("Ciphered text", output, dataLen);
      XORCipher(output, key, output, dataLen, keyLen);
      print_hex("Deciphered text", output, dataLen);
    }
    

    The output is

    Original text(0000): 54 68 65 20 71 75 69 63 6b 20 62 72 6f 77 6e 20 | The quick brown  |
    Original text(0010): 66 6f 78 20 6a 75 6d 70 73 20 6f 76 65 72 20 74 | fox jumps over t |
    Original text(0020): 68 65 20 6c 61 7a 79 20 64 6f 67 2e             | he lazy dog.     |
    The quick brown fox jumps over the lazy dog.
    ----
    Ciphered text(0000): 27 0d 06 52 14 01 1a 06 08 52 07 06 1c 12 0d 52 | '..R.....R.....R |
    Ciphered text(0010): 03 1b 0b 45 09 07 08 04 00 45 0c 04 00 06 53 11 | ...E.....E....S. |
    Ciphered text(0020): 0b 17 45 18 12 1f 1a 52 01 1b 14 4b             | ..E....R...K     |
    '
    RR
    RE  
    ----
    Deciphered text(0000): 54 68 65 20 71 75 69 63 6b 20 62 72 6f 77 6e 20 | The quick brown  |
    Deciphered text(0010): 66 6f 78 20 6a 75 6d 70 73 20 6f 76 65 72 20 74 | fox jumps over t |
    Deciphered text(0020): 68 65 20 6c 61 7a 79 20 64 6f 67 2e             | he lazy dog.     |
    The quick brown fox jumps over the lazy dog.
    ----
    

    (Note I'm deciphering the output back into output – that's fine in this instance since we know the cipher function works byte by byte.)

How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum