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;
}
Author by
Will03uk
Updated on June 04, 2022Comments
-
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 over 12 yearsIt's probably worth mentioning that this is exactly how you would write it in C++ also.
-
Will03uk over 12 yearsGood solution for the key length; I didn't think about %.
-
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 over 12 yearsIf 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 over 12 yearsThe returned string is not NULL terminated here.
-
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 over 12 yearsGood catch, @MikeSteinert - fixed.
-
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 over 12 yearsAgain, 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 over 12 yearsThis 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 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 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.