•

Check out our Community Blogs

Register and join over 40,000 other developers!

### Recent Blog Entries

• phi

I love this community !

# C Tutorial - XOR Encryption

encryption

9 replies to this topic

CC Newcomer

• Just Joined
• 17 posts

Posted 29 June 2009 - 06:48 AM

First of all, XOR encryption alone is very easy to create and can be easily broken (especially if a weak key is used). This tutorial assumes no responsibility for the quality of encryption.

Now, the first thing to now about XOR encryption is what exactly an XOR operation is. XOR stands for exclusive-or, it is a logical operand. XOR returns true if one and only one of the two arguments is true. A few examples:

1 xor 0 = 1
0 xor 1 = 1
1 xor 1 = 0
0 xor 0 = 0

Notice that if you were to xor the result against the key you will end up with the original value. This is how decrypting XOR encryption works. XOR is a symmetrical operation, so if you encrypt a file and then encrypt it again with the same key you will receive the original plaintext.

Now the XOR encryption uses this operand to cycle through each bit of plaintext and XOR's it against a key. The longer and more random a key is, the stronger the encryption.

The algorithm itself is the focus of this tutorial. The remainder of the program (I/O, etc) will be posted at the bottom but not explained outside of comments.

```void encrypt_data(FILE* input_file, FILE* output_file, char* key)
{
int key_count = 0; //Used to restart key if strlen(key) < strlen(encrypt)
int encrypt_byte;

//Loop through each byte of file until EOF
while( (encrypt_byte = fgetc(input_file)) != EOF)
{
//XOR the data and write it to a file
fputc(encrypt_byte ^ key[key_count], output_file);

//Increment key_count and start over if necessary
key_count++;
if(key_count == strlen(key))
key_count = 0;
}
}
```

In C (and many other languages) the ^ is the character that represents XOR.

encrypt_data() takes an input and output file and a key to encrypt with. fgetc() returns the next character from the input stream (our file). We XOR the current character of the file against the corresponding index of key. We then use fputc (it places the given character into an output stream) to place the XOR'ed data into out output file. Finally, we loop key to the index of 0 if we have reached the end of key.

Again, your encryption is only as strong as your key. I would not recommend this for any serious encryption (there are MANY MANY better methods of encryption). I have written this purely as a learning resource and an introduction to cryptography. Below is the source code in whole:

```//XOR Encryption

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

#define MAX_SIZE 256

void strip_newline(char* to_strip);
void encrypt_data(FILE* input_file, FILE* output_file, char *key);

int main(int argc, char* argv[])
{
//Check for valid number of arguments
if (argc != 3)
{
printf("Invalid number of arguments. %d arguments were supplied.\n", argc);
printf("Usage: %s inputfile outputfile\n", argv[0]); //Usage: ./xortest inputfile outputfile
exit(0);
}

FILE* input;
FILE* output;

//Open input and output files
input = fopen(argv[1], "r");
output = fopen(argv[2], "w");

//Check input file
if (input == NULL)
{
exit(0);
}

//Check output file
if (output == NULL)
{
printf("Output file cannot be written to.\n");
exit(0);
}

//Key strings
char *key = malloc(MAX_SIZE);

//Prompt for key
printf("Passphrase: ");

fgets(key, MAX_SIZE, stdin);

printf("Encrypting %s\n", argv[1]);

//strip newlines
strip_newline(key);

//XOR data and write it to file
encrypt_data(input, output, key);

printf("Encrypted data written to %s\n", argv[2]);

//Release memory
free(key);

//Close files
fclose(input);
fclose(output);

return 0;

}

void encrypt_data(FILE* input_file, FILE* output_file, char* key)
{
int key_count = 0; //Used to restart key if strlen(key) < strlen(encrypt)
int encrypt_byte;

while( (encrypt_byte = fgetc(input_file)) != EOF) //Loop through each byte of file until EOF
{
//XOR the data and write it to a file
fputc(encrypt_byte ^ key[key_count], output_file);

//Increment key_count and start over if necessary
key_count++;
if(key_count == strlen(key))
key_count = 0;
}
}

void strip_newline(char* to_strip)
{
//remove newlines
if (to_strip[strlen(to_strip) - 1] == '\n')
{
to_strip[strlen(to_strip) - 1] = '\0';
}
}
```

I hope you found this tutorial useful!

Edited by ShadenSmith, 29 June 2009 - 08:54 AM.

• 3

### #2 WingedPanther73

WingedPanther73

A spammer's worst nightmare

• Moderator
• 17757 posts
• Location:Upstate, South Carolina
• Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
• Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others

Posted 29 June 2009 - 07:44 AM

Very nice. I think it's worth pointing out that to decrypt your data, you simply "encrypt" the encrypted file with the same key.
• 0

Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

My MineCraft server site: http://banishedwings.enjin.com/

CC Newcomer

• Just Joined
• 17 posts

Posted 29 June 2009 - 08:52 AM

Yes, that's a very important point that I forgot to mention. I'll fix that now. Thanks.
• 0

### #4 Guest_Jordan_*

Guest_Jordan_*
• Guest

Posted 29 June 2009 - 08:54 AM

Very nice! +rep
• 0

CC Newcomer

• Just Joined
• 17 posts

Posted 29 June 2009 - 09:04 AM

Thanks Jordan! Codecall is really a great community. I'd like to contribute as much as I can to it.
• 0

### #6 WIREDTECH

WIREDTECH

CC Lurker

• Just Joined
• 1 posts

Posted 07 January 2010 - 07:34 AM

Can someone help me understand how to XOR this..what is the process? I have the results but I need to know how to get there:

L1: 941FEA4F2B9E7D41 # Mkey Left part 1
L2: C5A2AD40F2A8B733 # Mkey Left part 2

X1: 51BD470FD936CA72 # XOR L1 & L2

Thank you!
• 0

### #7 WingedPanther73

WingedPanther73

A spammer's worst nightmare

• Moderator
• 17757 posts
• Location:Upstate, South Carolina
• Programming Language:C, C++, PL/SQL, Delphi/Object Pascal, Pascal, Transact-SQL, Others
• Learning:Java, C#, PHP, JavaScript, Lisp, Fortran, Haskell, Others

Posted 07 January 2010 - 08:19 AM

Convert them to binary, XOR the binary representation, convert back to hexadecimal.
• 0

Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog

My MineCraft server site: http://banishedwings.enjin.com/

### #8 dcs

dcs

CC Devotee

• Just Joined
• 730 posts

Posted 31 January 2010 - 08:24 PM

```input = fopen(argv[1], [COLOR="Red"]"r"[/COLOR]);
output = fopen(argv[2], [COLOR="Red"]"w"[/COLOR]);
```
Wouldn't you want to open the files in binary mode to avoid the possibility of text mode translation of bytes?
• 0

### #9 lthreed

lthreed

CC Newcomer

• Just Joined
• 18 posts

Posted 07 March 2010 - 07:13 PM

What you've described is essentially a one-time pad. And with this the only weak key is one of all 0's
• 0

### #10 boufon

boufon

CC Lurker

• Just Joined
• 1 posts

Posted 16 March 2016 - 01:10 AM

There is a small bug in the source code above. In the function "encrypt_data" the lines

"

if(key_count == strlen(key))

key_count = 0;

"

must be replaced by

"

if(key_count + offset == strlen(key))
{
offset = 0;
key_count = 0;
}

"

here is the full source code

//XOR Encryption

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

#define MAX_SIZE 256

void strip_newline(char* to_strip);
void encrypt_data(FILE* input_file, FILE* output_file, char *key, int key_count);

int main(int argc, char* argv[])
{
//Check for valid number of arguments
if (argc < 3)
{
printf("Nb de parametres incorrect. %d paramètres fournis.\n", argc);
printf("Usage: %s inputfile outputfile\n", argv[0]); //Usage: ./xortest inputfile outputfile
exit(0);
}

FILE* input;
FILE* output;

//Open input and output files
input = fopen(argv[1], "r");

//Check input file
if (input == NULL)
{
exit(0);
}

//Key strings
char *key = malloc(MAX_SIZE);

if(argc == 3){
//Prompt for key
printf("Passphrase: ");

fgets(key, MAX_SIZE, stdin);
}
else{
if(argv[3][0] == '0' && argv[3][1] == 'x'){
char *c = &argv[3][2];
int i = 0;
unsigned int a;
char cc;
printf ("len de c: %d",len);
while(i < len){
char *s = malloc(5*sizeof(char));
s[0] = '0';
s[1] = 'x';
s[2] = c[i++];
s[3] = c[i++];
s[4] = '\0';
sscanf(s, "%x", &a);
cc=(char)a;
key[i/2-1]=cc;
free(s);

}
}
else{
strcpy(key, argv[3]);
}
}
int withOffset = 0;
if(argc == 5 && strcmp(argv[4], "-o") == 0){
withOffset = 1;
}
printf("Encrypting %s\n", argv[1]);

//strip newlines
strip_newline(key);

// If offset arg is given
if(withOffset){
int offset;
for(offset = 0; offset < strlen(key); ++offset){

char *file;
file = malloc(MAX_SIZE);
sprintf(file, "%s_%d", argv[2], offset);
output = fopen(file, "w");
//Check output file
if (output == NULL)
{
printf("Output file cannot be written to.\n");
exit(0);
}
//XOR data and write it to file

encrypt_data(input, output, key, offset);
printf("Encrypted data written to %s\n", file);
fclose(output);
// Don't forget to set file cursor to begining
rewind(input);
}
}
else{

output = fopen(argv[2], "w");
//Check output file
if (output == NULL)
{
printf("Output file cannot be written to.\n");
exit(0);
}
encrypt_data(input, output, key, 0);
printf("Encrypted data written to %s\n", argv[2]);
fclose(output);
}

//Release memory
free(key);

//Close files
fclose(input);

return 0;

}

void encrypt_data(FILE* input_file, FILE* output_file, char* key, int offset)//Used to restart key if strlen(key) < strlen(encrypt)
{
int encrypt_byte;
int key_count = 0;

while( (encrypt_byte = fgetc(input_file)) != EOF) //Loop through each byte of file until EOF
{
//XOR the data and write it to a file
fputc(encrypt_byte ^ key[offset+key_count], output_file);

//Increment key_count and start over if necessary
key_count++;
if(key_count + offset == strlen(key))
{
offset = 0;
key_count = 0;
}
}
}

void strip_newline(char* to_strip)
{
//remove newlines
if (to_strip[strlen(to_strip) - 1] == '\n')
{
to_strip[strlen(to_strip) - 1] = '\0';
}
}

• 0

### Also tagged with one or more of these keywords: encryption

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download