diff options
Diffstat (limited to 'encode.c')
-rw-r--r-- | encode.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/encode.c b/encode.c new file mode 100644 index 0000000..2aba6cc --- /dev/null +++ b/encode.c @@ -0,0 +1,70 @@ +#include <stdio.h> +#include <stdlib.h> + +//base64Encode: Encodes binary input data into base64. Takes a pointer to a '\0' terminated input string and the size of the string, not including '\0' (e.g. strlen(string)) +//Returns pointer to '\0' terminated string on success. Returns NULL if size of input string is zero, or if malloc fails +char *base64Encode(unsigned char *input, int size) +{ +char index64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//lookup table for base64 characters + +if (!size){return NULL;}//Catches the case of feeding the function a negative or 0 length. +unsigned char *output = malloc( (((size + 2) / 3) << 2)+1 * sizeof(unsigned char) );//malloc output to the correct size. (length in input string +33%, rounded up to whole number) (+1 for added null char) +if (!output){fprintf(stderr,"Malloc Failed!\n"); return NULL;} + +int base64Val;//base64Val is the base64 value resulted when all matching bits values are added together +int i = 0;//i is located at the position of the char currently being processed + +int outputPos = 0;//i and the output string of base64 characters don't match up + +while (size)//keep looping until all characters have been processed +{ + base64Val=0; + if (input[i] & 4){++base64Val;} + if (input[i] & 8){base64Val += 2;} + if (input[i] & 16){base64Val += 4;} + if (input[i] & 32){base64Val += 8;} + if (input[i] & 64){base64Val += 16;} + if (input[i] & 128){base64Val += 32;} + output[outputPos++] = index64[base64Val];//the resulting base64 char is placed into output and then outputPos is incremented to the next position for the next char + + //this code may need to read into the NULL char, so it's imporant that the NULL char is there to prevent reading past the buffer + ++i; + base64Val=0; + if (input[i] & 16){++base64Val;} + if (input[i] & 32){base64Val += 2;} + if (input[i] & 64){base64Val += 4;} + if (input[i] & 128){base64Val += 8;} + if (input[i-1] & 1){base64Val += 16;} + if (input[i-1] & 2){base64Val += 32;} + output[outputPos++] = index64[base64Val]; + //even if there are no more characters to process at this stage; "===" is not permitted, "A==" should be printed instead + if ((size == 1)){output[outputPos] = '='; output[outputPos+1] = '='; output[outputPos+2] = '\0'; return output;} + + //read the six bits from one before i and then read the two upper bits as 1 and 2 + ++i; + base64Val=0; + if (input[i] & 64){++base64Val;} + if (input[i] & 128){base64Val += 2;} + if (input[i-1] & 1){base64Val += 4;} + if (input[i-1] & 2){base64Val += 8;} + if (input[i-1] & 4){base64Val += 16;} + if (input[i-1] & 8){base64Val += 32;} + output[outputPos++] = index64[base64Val]; + if (size == 2){output[outputPos] = '='; output[outputPos+1] = '\0'; return output;}//if are two letters left at here; "=\0" should be printed + + base64Val=0; + if (input[i] & 1){++base64Val;} + if (input[i] & 2){base64Val += 2;} + if (input[i] & 4){base64Val += 4;} + if (input[i] & 8){base64Val += 8;} + if (input[i] & 16){base64Val += 16;} + if (input[i] & 32){base64Val += 32;} + output[outputPos++] = index64[base64Val]; + + ++i;//process next i char + size -= 3;//3 from length since 24 bits (3 chars) are processed at once +} + +output[outputPos] = '\0'; +return output; +} |