Created
January 25, 2018 06:05
-
-
Save lqt0223/9d774864306d2308966e8b8b13c04b70 to your computer and use it in GitHub Desktop.
22 Base64 Encoding
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#define B64_UNIT_BYTE_SIZE 3 | |
int b64_readbytes(char* src, int count) { | |
int result = 0; | |
for (int i = 0; i < count; i++, src++) { | |
result += *src; | |
if (i != count - 1) { | |
result <<= 8; | |
} | |
} | |
return result; | |
} | |
int b64_cleanbuffer(char* dest, int count) { | |
for (int i = 0; i < count; i++) { | |
dest[i] = 0x0; | |
} | |
return 0; | |
} | |
int b64_map_to_ascii_code(int b64code) { | |
// + | |
if (b64code == 62) { | |
return 43; | |
// / | |
} else if (b64code == 63) { | |
return 47; | |
// lower case | |
} else if (b64code >= 26 && b64code <= 51) { | |
return b64code + 71; | |
// upper case | |
} else if (b64code >= 0 && b64code <= 25) { | |
return b64code + 65; | |
// numerical | |
} else if (b64code >= 52 && b64code <= 61) { | |
return b64code - 4; | |
// error | |
} else { | |
return -1; | |
} | |
} | |
int b64_strcpy(char* dest, char* src, int size) { | |
for (int i = 0; i < size; i++) { | |
dest[i] = src[i]; | |
} | |
return 0; | |
} | |
int b64_encode_unit(char* encoded, int src, int padsize) { | |
int mask1 = 0x3F; | |
int mask2 = mask1 << 6; | |
int mask3 = mask2 << 6; | |
int mask4 = mask3 << 6; | |
encoded[0] = b64_map_to_ascii_code((src & mask4) >> 18); | |
encoded[1] = b64_map_to_ascii_code((src & mask3) >> 12); | |
encoded[2] = b64_map_to_ascii_code((src & mask2) >> 6); | |
encoded[3] = b64_map_to_ascii_code((src & mask1)); | |
if (padsize == 1) { | |
encoded[3] = 61; | |
} else if (padsize == 2) { | |
encoded[2] = 61; | |
encoded[3] = 61; | |
} | |
encoded[4] = 0x0; | |
return 0; | |
} | |
int b64_encode_str(char* dest, char* src, int src_size) { | |
char* encoded = (char*)malloc(sizeof(char) * 4); | |
int remainder = src_size % 3; | |
int i = 0; | |
while (i < src_size - remainder) { | |
int byte = b64_readbytes(src + i, B64_UNIT_BYTE_SIZE); | |
b64_encode_unit(encoded, byte, 0); | |
b64_strcpy(dest, encoded, 4); | |
i += B64_UNIT_BYTE_SIZE; | |
dest += 4; | |
} | |
// handling remainder | |
if (remainder == 1) { | |
int byte = src[src_size - 1]; | |
byte <<= 16; | |
b64_encode_unit(encoded, byte, 2); | |
b64_strcpy(dest, encoded, 4); | |
} else if (remainder == 2) { | |
int byte = (src[src_size - 2] << 8) + src[src_size - 1]; | |
byte <<= 8; | |
b64_encode_unit(encoded, byte, 1); | |
b64_strcpy(dest, encoded, 4); | |
} | |
free(encoded); | |
return 0; | |
} | |
int b64_encode_file_write_header(FILE* fp, char* mime) { | |
fprintf(fp, "data:%s;base64,", mime); | |
return 0; | |
} | |
int b64_encode_file(char* dest, char* src, char* mime) { | |
FILE* fp = fopen(src, "rb"); | |
FILE* fp_out = fopen(dest, "w"); | |
b64_encode_file_write_header(fp_out, mime); | |
char* encoded = (char*)malloc(sizeof(char) * 4); | |
int read = 0, byte = 0, count = 0; | |
while((read = fgetc(fp)) != EOF) { | |
switch (count) { | |
case 0: | |
case 1: { | |
byte += read; | |
byte <<= 8; | |
break; | |
} | |
case 2: { | |
byte += read; | |
b64_encode_unit(encoded, byte, 0); | |
fwrite(encoded, 4, 1, fp_out); | |
b64_cleanbuffer(encoded, 4); | |
byte = 0; | |
break; | |
} | |
} | |
count++; | |
if (count == 3) { | |
count = 0; | |
} | |
} | |
// handling remainder | |
if (count == 2) { | |
byte <<= 16; | |
b64_encode_unit(encoded, byte, 1); | |
fwrite(encoded, 4, 1, fp_out); | |
} else if (count == 1) { | |
byte <<= 8; | |
b64_encode_unit(encoded, byte, 2); | |
fwrite(encoded, 4, 1, fp_out); | |
} | |
fclose(fp_out); | |
free(encoded); | |
return 0; | |
} | |
int main() { | |
// read file from src, write the base64 encoded data uri to dest | |
char mime[] = "image/jpeg"; | |
char src[] = "Directory of binary file to encode..."; | |
char dest[] = "Directory of encoded data uri to export..."; | |
b64_encode_file(dest, src, mime); | |
// encode string from src, write the base64 encoded string to dest | |
char src2[] = "hello"; | |
char dest2[1024]; | |
int size = strlen(src2); | |
b64_encode_str(dest2, src2, size); | |
printf("%s\n", dest2); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment