simple XOR algorithm

19,200

Solution 1

OK, I hacked around for a minute and came up with this (only vaguely tested):

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

char * xorencrypt(char * message, char * key) {
    size_t messagelen = strlen(message);
    size_t keylen = strlen(key);

    char * encrypted = malloc(messagelen+1);

    int i;
    for(i = 0; i < messagelen; i++) {
        encrypted[i] = message[i] ^ key[i % keylen];
    }
    encrypted[messagelen] = '\0';

    return encrypted;
}

int main(int argc, char * argv[]) {
    char * message = "test message";
    char * key = "abc";

    char * encrypted = xorencrypt(message, key);
    printf("%s\n", encrypted);
    free(encrypted);

    return 0;
}

Note that the function xorencrypt allocates and returns a new string, so it's the caller's responsibility to free it when done.

Solution 2

C is very close to Assembler, so this example is short:

while (*string)
    *string++ ^= key;

assuming char *string; and char key.

Solution 3

For what it's worth, combine the answers from @ott-- & @Tim to form Xortron.

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

char *xor(char *string, const char *key)
{
    char *s = string;
    size_t length = strlen(key), i = 0;
    while (*s) {
            *s++ ^= key[i++ % length];
    }
    return string;
}

int main(int argc, char **argv)
{
    const char *key = "abc";
    if (argc < 2) {
            fprintf(stderr, "%s: no input\n", argv[0]);
            return EXIT_FAILURE;
    }
    printf("%s\n", xor(xor(argv[1], key), key));
    return EXIT_SUCCESS;
}
Share:
19,200
Will03uk
Author by

Will03uk

Updated on June 04, 2022

Comments

  • Will03uk
    Will03uk almost 2 years

    Although I've used C++ a lot, I'm struggling with the C differences (mainly in strings).

    Could you please show me a simple single function that encrypts a message with a key using XOR comparison.

    Thank-you

    EDIT: Both the key and the message are char*

  • Mike Steinert
    Mike Steinert over 12 years
    It's probably worth mentioning that this is exactly how you would write it in C++ also.
  • Will03uk
    Will03uk over 12 years
    Good solution for the key length; I didn't think about %.
  • Will03uk
    Will03uk over 12 years
    @Mike I know, but manipulating cstrings are somewhat new to me; do you need to initialize strings to '\0' after malloc?
  • Tim
    Tim over 12 years
    If you're not sure of the length, yes; you'll note my solution above takes care of that issue instead by only allocating a string of the same length as the original message (so you're sure the entire string will be filled with data, and doesn't need \0-filling).
  • Mike Steinert
    Mike Steinert over 12 years
    The returned string is not NULL terminated here.
  • Mike Steinert
    Mike Steinert over 12 years
    @Will03uk You don't have to initialize the string data if you plan to write it, however should make sure it is NULL-terminated.
  • Tim
    Tim over 12 years
    Good catch, @MikeSteinert - fixed.
  • Rag
    Rag over 12 years
    @Will03uk You need to initialize memory before you can read it, but you can write to it without a problem. And you never have to fill a block of memory with zeros when working with strings, since string functions only read up to the first \0. However, you will see that zero-filling be done occasionally because people (ab)use strncat for security reasons. Really the only time you need to do that is when working with fixed-width fields, which are used in systems programming.
  • Will03uk
    Will03uk over 12 years
    Again, sorry for lack of clarity; by initializing, I meant NULL-terminating the first byte before the use of a function such as strcat. Thank-you for the help
  • President James K. Polk
    President James K. Polk over 12 years
    This really won't work reliably. The problem is that the encrypted string may contain any character at any point in the string, including '\0'. Thus you have no way of knowing where the end of the encrypted string is.
  • Tim
    Tim over 12 years
    @GregS: true, and I considered that, but the OP hasn't specified that he needs that information (and it's trivially obtainable from strlen(message) anyway).
  • Tim
    Tim over 12 years
    @GregS: Sure there is, as a guard in the case where (a) the XOR'd string doesn't contain a \0 and (b) the programmer is lazy and tries to depend on its null-termination without finding the length by hand. Rare and undesirable situation? Probably. Defensive programming? Yes.