A better implementation (I think):
Code:
#include <stdio.h>
#include <string.h>
static void printblock( char *, char *, size_t );
static void encrypt( char *, char *, char *, size_t, size_t );
#define decrypt(p,e,k,ts,ks) encrypt( (p), (e), (k), (ts), (ks) )
int main( void )
{
size_t size, ksize;
static char msg[] = "Hello, world! I am a plain text!";
static char key[] = "HELLO";
// FIXME: Could be dynamically allocated...
char enc[100], dec[100];
size = strlen( msg );
ksize = strlen( key );
printf( "Plain text: \"%s\".\n\n", msg );
printblock( "msg[]", msg, size );
encrypt( enc, msg, key, size, ksize );
puts("***Warning***: Notice the first byte" );
printblock( "enc[]", enc, size );
decrypt( dec, enc, key, size, ksize );
printblock( "dec[]", dec, size );
dec[size] = '\0'; // marks the end of the string.
printf( "Decoded text: \"%s\".\n", dec );
}
// prints the block pointed by p, with size bytes.
void printblock( char *prompt, char *p, size_t size )
{
size_t offset = 0;
char *oldp;
oldp = p;
printf( "%s:\n%08zx:", prompt, offset );
while ( size-- )
{
printf( " %02x", *p );
p++;
offset++;
if (p - oldp > 15)
{
oldp = p;
printf("\n%08zx:", offset);
}
}
puts("\n");
}
// We are not dealing with strings here, but with blocks of data.
// Assumptions:
// encp, plainp and keyp are different pointers (should use 'restrict' here).
// encp is the only block pointed which will be changed ('enc' from 'encrypted text').
// plainp (pointer to plaintext) and keyp (pointer to key).
// tsize is the 'plain text' block size.
// ksize is the key size.
void encrypt( char *encp, char *plainp, char *keyp, size_t tsize, size_t ksize )
{
char *kp = keyp;
ssize_t ks = ksize;
while ( tsize-- )
{
*encp++ = *plainp++ ^ *kp++;
// Resets the auxiliary key pointer if we got at the
// end of the key buffer...
if ( --ks <= 0 )
{
ks = ksize;
kp = keyp;
}
}
}
Result:
Code:
$ ./test
Plain text: "Hello, world! I am a plain text!".
msg[]:
00000000: 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 20 49 20
00000010: 61 6d 20 61 20 70 6c 61 69 6e 20 74 65 78 74 21
00000020:
***Warning***: Notice the first byte
enc[]:
00000000: 00 20 20 20 20 64 65 3b 23 3d 24 21 6d 6c 06 68
00000010: 24 21 6c 2e 68 35 20 2d 26 26 65 38 29 37 3c 64
00000020:
dec[]:
00000000: 48 65 6c 6c 6f 2c 20 77 6f 72 6c 64 21 20 49 20
00000010: 61 6d 20 61 20 70 6c 61 69 6e 20 74 65 78 74 21
00000020:
Decoded text: "Hello, world! I am a plain text!"
The "encoded" part, printed with hd:
Code:
$ echo -ne "\x00\x20\x20\x20\x20\x64\x65\x3b\x23\x3d\x24\x21\x6d\x6c\x06\x68\x24\x21\x6c\x2e\x68\x35\x20\x2d\x26\x26\x65\x38\x29\x37\x3c\x64" | hd
00000000 00 20 20 20 20 64 65 3b 23 3d 24 21 6d 6c 06 68 |. de;#=$!ml.h|
00000010 24 21 6c 2e 68 35 20 2d 26 26 65 38 29 37 3c 64 |$!l.h5 -&&e8)7<d|
00000020