
This is a very simple way to encrypt text using the xor operator ^ in C. Xor is one of the bitwise operators in C like & (bitwise and ) and | (bitwise or).
Don’t use bitwise Xor for anything that you really have to keep secret. There are much more secure ways, but xor can be used for lightweight stuff. For example say you want to hide some text in a program so that anyone looking at the text in a debugger would not recognise the text.
What is Xor?
You may know & and | already. In single bits where a is either 1 or 0, a & 1 = 0. a | 1 =1. Xor works like this:
a ^ 1 = 0 (if a =1) or 1 (if a = 0). In other words if you Xor any bit with 1, it flips that bit. Here are the four possible values:
1 ^ 0 = 1 1 ^ 1 = 0 0 ^ 1 = 1 0 ^ 0 = 0
Simply put if the two bits are the same you get 0, if they are different, you get 1.
So how do we encrypt text with xor?
When you Xor a byte, you flip several of the bits. The more bits that get flipped, the less easy it is to recognise the original. So we really want to only flip with bytes that have 4-8 bits set to 1. We would never xor anything with 1, 2, 4 etc as those are only single bits.
If you xor 70 (the ASCII code for F) with 1 you get 70 (64 + 4 + 2) becoming 71 which is G. That’s a rather poor way to obscure text.
I used a function ti count the bits and then populated an array with just the values with 4 bits set to 1. The first five values are:
15 (00001111) 23 (00010111) 27 (00011011) 29 (00011101) 30 (00011110)
All in all there are 163 values out of 0-255 that have four or more bits set.
So to obscure the text, just index through it character by character and xor that character with the next value out of the xorValues array.
Here’s the code to do it. It takes a plain text message “This is the message to hide”, generates the XorValues array then calls a function xorText that does the obscuring.
Finally, print out the original text (char by char) as int alongside with the encrypted value.
Here is the source code.
#include <stdio.h>
#include <memory.h>
unsigned char xorValues[256];
unsigned char hiddenValues[256];
int numValues=0;
int numChars;
// Fast bit counter
unsigned char CountBits(int value){
return (value * 01001001001ULL & 042104210421ULL) % 017;
}
// fills array xorValues with values from 0-255 that have 4 or more 1 bits set
void genXorValues() {
int index=0;
for (int i=0;i<256;i++){
if (CountBits(i)>=4){
xorValues[index++]=i;
}
}
numValues = index;
}
// Xors all chars in text and stores in hiddenValues
void xorText(char * text){
memset(hiddenValues,0,sizeof(hiddenValues));
int xorIndex=0;
for (int i=0;i<numChars;i++){
hiddenValues[i] = text[i] ^ xorValues[xorIndex++];
if (xorIndex==numValues){
xorIndex=0;
}
}
}
int main(int argc, char* argv[])
{
char * plainText="This is the message to hide";
numChars = strlen(plainText);
genXorValues();
xorText(plainText);
for (int i=0;i<numChars;i++){
printf("%3d %3d\n",plainText[i],hiddenValues[i]);
}
return 0;
}
Here’s the first ten chars of the message printed as ints with the encrypted value.
84 91
104 127
105 114
115 110
32 62
105 118
115 84
32 11
116 89
104 70
You can see that the first space (32) becomes 62 but the second one is 11.
If the message had been longer than 163 bytes then the xorIndex variable resets back to 0 and reuses the 163 values. Remember this is not meant to be the last word in high tech encryption, it is very light weight!