#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Macro definitions base64 */
#define TABLELEN 63
#define BUFFFERLEN 128
#define ENCODERLEN 4
#define ENCODEROPLEN 0
#define ENCODERBLOCKLEN 3
#define PADDINGCHAR '='
#define BASE64CHARSET "ABCDEFGHIJKLMNOPQRSTUVWXYZ"\
"abcdefghijklmnopqrstuvwxyz"\
"0123456789"\
"+/?!"\
"";
/* Function prototypes */
int Base64Encode(char *input, char *output, int oplen);
int encodeblock(char *input, char *output, int oplen);
int Base64Decode(char *input, char *output, int oplen);
int decodeblock(char *input, char *output, int oplen);
/* Its always better to move the macros and function prototypes to a header file */
int decodeblock(char *input, char *output, int oplen){
int rc = 0;
char decodedstr[ENCODERLEN + 1] = "";
decodedstr[0] = input[0] << 2 | input[1] >> 4;
decodedstr[1] = input[1] << 4 | input[2] >> 2;
decodedstr[2] = input[2] << 6 | input[3] >> 0;
strncat(output, decodedstr, oplen-strlen(output));
return rc;
}
int Base64Decode(char *input, char *output, int oplen){
char *charval = 0;
char decoderinput[ENCODERLEN + 1] = "";
char encodingtabe[TABLELEN + 1] = BASE64CHARSET;
int index = 0, asciival = 0, computeval = 0, iplen = 0, rc = 0;
iplen = strlen(input);
while(index < iplen){
asciival = (int)input[index];
if(asciival == PADDINGCHAR){
rc = decodeblock(decoderinput, output, oplen);
break;
}else{
charval = strchr(encodingtabe, asciival);
if(charval){
decoderinput[computeval] = charval - encodingtabe;
computeval = (computeval + 1) % 4;
if(computeval == 0){
rc = decodeblock(decoderinput, output, oplen);
decoderinput[0] = decoderinput[1] =
decoderinput[2] = decoderinput[3] = 0;
}
}
}
index++;
}
return rc;
}
int encodeblock(char *input, char *output, int oplen){
int rc = 0, iplen = 0;
char encodedstr[ENCODERLEN + 1] = "";
char encodingtabe[TABLELEN + 1] = BASE64CHARSET;
iplen = strlen(input);
encodedstr[0] = encodingtabe[ input[0] >> 2 ];
encodedstr[1] = encodingtabe[ ((input[0] & 0x03) << 4) |
((input[1] & 0xf0) >> 4) ];
encodedstr[2] = (iplen > 1 ? encodingtabe[ ((input[1] & 0x0f) << 2) |
((input[2] & 0xc0) >> 6) ] : PADDINGCHAR);
encodedstr[3] = (iplen > 2 ? encodingtabe[ input[2] & 0x3f ] : PADDINGCHAR);
strncat(output, encodedstr, oplen-strlen(output));
return rc;
}
int Base64Encode(char *input, char *output, int oplen){
int rc = 0;
int index = 0, ipindex = 0, iplen = 0;
char encoderinput[ENCODERBLOCKLEN + 1] = "";
iplen = strlen(input);
while(ipindex < iplen){
for(index = 0; index < 3; index++){
if(ipindex < iplen){
encoderinput[index] = input[ipindex];
}else{
encoderinput[index] = 0;
}
ipindex++;
}
rc = encodeblock(encoderinput, output, oplen);
}
return rc;
}
/* RC4: */
/* Prototype the encryption/decryption function */
char *EnDeCrypt(const char *pszText, int iTextLen, const char *pszKey);
void swapints(int *array, int ndx1, int ndx2);
char *EnDeCrypt(const char *pszText, int iTextLen, const char *pszKey)
/* ;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;::: This routine does all the work. Call it both to ENcrypt :::
;::: and to DEcrypt your data. :::
;::: You MUST free the returned pointer when no longer needed :::
;::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: */
{
char *cipher; /* Output buffer */
int a, b, i=0, j=0, k; /* Ambiguously named counters */
int ilen; /* Length of a string */
int sbox[256]; /* Encryption array */
int key[256]; /* Numeric key values */
ilen = strlen(pszKey);
for (a=0; a < 256; a++)
{
key[a] = pszKey[a % ilen];
sbox[a] = a;
}
for (a=0, b=0; a < 256; a++)
{
b = (b + sbox[a] + key[a]) % 256;
swapints(sbox, a, b);
}
cipher = (char *)malloc(iTextLen);
for (a=0; a < iTextLen; a++)
{
i = (i + 1) % 256;
j = (j + sbox[i]) % 256;
swapints(sbox, i, j);
k = sbox[(sbox[i] + sbox[j]) % 256];
cipher[a] = pszText[a] ^ k;
}
return cipher;
}
void swapints(int *array, int ndx1, int ndx2)
{
int temp = array[ndx1];
array[ndx1] = array[ndx2];
array[ndx2] = temp;
}
int main()
{
char buf[256], passwd[16], *pEncrypted, *pDecrypted, *pch;
int ix, iLen;
int rc = 0;
char input[BUFFFERLEN + 1] = "";
char encodedoutput[BUFFFERLEN + 1] = "";
char decodedoutput[BUFFFERLEN + 1] = "";
for (;;)
{
printf("\nString to encrypt (just Enter to exit): ");
fgets(buf, sizeof(buf), stdin);
for (ix = strlen(buf) - 1; (ix >= 0) && (buf[ix] == 10); ix--)
buf[ix] = 0;
if (!buf[0])
break;
printf("\nKey: ");
fgets(passwd, sizeof(passwd), stdin);
for (ix = strlen(passwd) - 1; (ix >= 0) && (passwd[ix] == 10); ix--)
passwd[ix] = 0;
if (!passwd[0])
break;
iLen = strlen(buf);
pEncrypted = EnDeCrypt(buf, iLen, passwd);
rc = Base64Encode(pEncrypted, encodedoutput, BUFFFERLEN);
printf("\nEncrypted output:\n");
printf(encodedoutput);
/* for (pch = pEncrypted, ix=0; ix < iLen; pch++, ix++)
{
if (!(ix % 20))
printf("\n");
printf("%1X ", (unsigned char)*pch);
} */
rc = Base64Decode(encodedoutput, decodedoutput, BUFFFERLEN);
pDecrypted = EnDeCrypt(decodedoutput, iLen, passwd);
pDecrypted[iLen] = 0; /* Null-terminate */
printf("\nDecrypted text: %s", pDecrypted);
free(pEncrypted);
free(pDecrypted);
}
return 0;
}
/*int main(void) {
int rc = 0;
char input[BUFFFERLEN + 1] = "";
char encodedoutput[BUFFFERLEN + 1] = "";
char decodedoutput[BUFFFERLEN + 1] = "";
printf("Enter a string: \n");
scanf("%[^\n]", input);
rc = Base64Encode(input, encodedoutput, BUFFFERLEN);
printf("Base64 Encoded value: %s\n", encodedoutput);
rc = Base64Decode(encodedoutput, decodedoutput, BUFFFERLEN);
printf("Base64 Decoded value: %s", decodedoutput);
system("PAUSE");
return rc;
}
*/