From 03332d7b509e0e2950aef579086064ecf02b654f Mon Sep 17 00:00:00 2001 From: Joe DF Date: Mon, 22 Sep 2014 01:00:27 -0400 Subject: add initial version --- .gitignore | 4 ++ BuildRun.bat | 7 ++++ base64.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 272 insertions(+) create mode 100644 BuildRun.bat create mode 100644 base64.c create mode 100644 test.c diff --git a/.gitignore b/.gitignore index 58bcbf8..60ca861 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ +*.exe +*.lnk +*.url + # Windows image file caches Thumbs.db ehthumbs.db diff --git a/BuildRun.bat b/BuildRun.bat new file mode 100644 index 0000000..874ac75 --- /dev/null +++ b/BuildRun.bat @@ -0,0 +1,7 @@ +@echo off +mkdir bin 2>NUL +cls +echo compiling... +gcc test.c base64.c -o bin\test.exe +echo running... +bin\test.exe \ No newline at end of file diff --git a/base64.c b/base64.c new file mode 100644 index 0000000..55b482f --- /dev/null +++ b/base64.c @@ -0,0 +1,133 @@ +#include + +/* + base64.c - by Joe DF (joedf@ahkscript.org) + Released under the MIT License + + Revision: 00:06 2014-09-22 + + Thank you for inspiration: + http://www.codeproject.com/Tips/813146/Fast-base-functions-for-encode-decode +*/ + + +unsigned int b64_int(unsigned int ch); +unsigned int b64e_size(unsigned int in_size); +unsigned int b64d_size(unsigned int in_size); +unsigned int b64_encode(const unsigned int* in, unsigned int in_len, unsigned char* out); +unsigned int b64_decode(const unsigned char* in, unsigned int in_len, unsigned int* out); + + +//Base64 char table - used internally for encoding +unsigned char b64_chr[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +//Base64 char table functions - used internally for decoding +unsigned int b64_int(unsigned int ch) { + + // ASCII to base64_int + // 65-90 Upper Case >> 0-25 + // 97-122 Lower Case >> 26-51 + // 48-57 Numbers >> 52-61 + // 43 Plus (+) >> 62 + // 47 Slash (/) >> 63 + // 61 Equal (=) >> 64~ + if (ch==43) + return 62; + if (ch==47) + return 63; + if (ch==61) + return 64; + if ((ch>47) && (ch<58)) + return ch + 4; + if ((ch>64) && (ch<91)) + return ch - 'A'; + if ((ch>96) && (ch<123)) + return (ch - 'a') + 26; + return 0; +} + +// in_size : the number bytes to be encoded. +// Returns the recommended memory size to be allocated for the output buffer excluding the null byte +unsigned int b64e_size(unsigned int in_size) { + + // size equals 4*floor((1/3)*(in_size+2)); + int i, j = 0; + for (i=0;i>2 ]; + out[k+1] = b64_chr[ ((s[0]&0x03)<<4)+((s[1]&0xF0)>>4) ]; + out[k+2] = b64_chr[ ((s[1]&0x0F)<<2)+((s[2]&0xC0)>>6) ]; + out[k+3] = b64_chr[ s[2]&0x3F ]; + j=0; k+=4; + } + } + + if (j) { + if (j==1) + s[1] = 0; + out[k+0] = b64_chr[ s[0]>>2 ]; + out[k+1] = b64_chr[ ((s[0]&0x03)<<4)+((s[1]&0xF0)>>4) ]; + if (j==2) + out[k+2] = b64_chr[ ((s[1]&0x0F)<<2) ]; + else + out[k+2] = '='; + out[k+3] = '='; + k+=4; + } + + out[k] = '\0'; + + return k; +} + +// in : buffer of base64 string to be decoded. +// in_len : number of bytes to be decoded. +// out : pointer to buffer with enough memory, user is responsible for memory allocation, receives "raw" binary +// returns size of output excluding null byte +unsigned int b64_decode(const unsigned char* in, unsigned int in_len, unsigned int* out) { + + unsigned int i=0, j=0, k=0, s[4]; + + for (i=0;i>4); + if (s[2]!=64) { + out[k+1] = ((s[1]&0x0F)<<4)+((s[2]&0x3C)>>2); + if ((s[3]!=64)) { + out[k+2] = ((s[2]&0x03)<<6)+(s[3]); k+=3; + } else { + k+=2; + } + } else { + k+=1; + } + j=0; + } + } + + return k; +} diff --git a/test.c b/test.c new file mode 100644 index 0000000..1a07c9c --- /dev/null +++ b/test.c @@ -0,0 +1,128 @@ +#include +#include +#include + +//Test values +/////////////////////////////////////////////////////////////// +#define STRING_A "9TrJ" +#define STRING_B "9TrJUQ==" +#define STRING_C "9TrJUfA=" + +#define HEXNUM_A {0xF5,0x3A,0xC9} +#define HEXNUM_B {0xF5,0x3A,0xC9,0x51} +#define HEXNUM_C {0xF5,0x3A,0xC9,0x51,0xF0} + +#define HEXSTR_A "0xF5 0x3A 0xC9" +#define HEXSTR_B "0xF5 0x3A 0xC9 0x51" +#define HEXSTR_C "0xF5 0x3A 0xC9 0x51 0xF0" +/////////////////////////////////////////////////////////////// + +#define NELEMS(x) (sizeof(x) / sizeof(x[0])) + +int test_b64_encode(); +int test_b64_decode(); +int hexputs(unsigned int* data, unsigned int len); +int compare(int *a, int *b, int l); +char *status(int boolean); + +int main() { + + puts("\nbase64.c [Test]"); + puts("------------------------------------"); + printf("%s : %s\n",HEXSTR_A,STRING_A); + printf("%s : %s\n",HEXSTR_B,STRING_B); + printf("%s : %s\n",HEXSTR_C,STRING_C); + puts("\nTesting b64_encode() ...\n"); + test_b64_encode(); + puts("\nTesting b64_decode() ...\n"); + test_b64_decode(); + puts("\n[END]"); + + return 0; +} + +int test_b64_encode() { + + int test_a[] = HEXNUM_A; + int test_b[] = HEXNUM_B; + int test_c[] = HEXNUM_C; + + int size_a = NELEMS(test_a); + int size_b = NELEMS(test_b); + int size_c = NELEMS(test_c); + + int out_size_a = b64e_size(size_a) + 1; + int out_size_b = b64e_size(size_b) + 1; + int out_size_c = b64e_size(size_c) + 1; + + unsigned char *out_a = malloc(out_size_a); + unsigned char *out_b = malloc(out_size_b); + unsigned char *out_c = malloc(out_size_c); + + out_size_a = b64_encode(test_a,size_a,out_a); + out_size_b = b64_encode(test_b,size_b,out_b); + out_size_c = b64_encode(test_c,size_c,out_c); + + printf("%s\t%s\n",status(!strcmp(out_a,STRING_A)),out_a); + printf("%s\t%s\n",status(!strcmp(out_b,STRING_B)),out_b); + printf("%s\t%s\n",status(!strcmp(out_c,STRING_C)),out_c); + + return 0; +} + +int test_b64_decode() { + + char test_a[] = STRING_A; + char test_b[] = STRING_B; + char test_c[] = STRING_C; + + int len_a = strlen(test_a); + int len_b = strlen(test_b); + int len_c = strlen(test_c); + + int out_size_a = b64d_size(len_a) + 1; + int out_size_b = b64d_size(len_b) + 1; + int out_size_c = b64d_size(len_c) + 1; + + unsigned int *out_a = malloc(out_size_a); + unsigned int *out_b = malloc(out_size_b); + unsigned int *out_c = malloc(out_size_c); + + out_size_a = b64_decode(test_a,len_a,out_a); + out_size_b = b64_decode(test_b,len_b,out_b); + out_size_c = b64_decode(test_c,len_c,out_c); + + int r_a[] = HEXNUM_A; + int r_b[] = HEXNUM_B; + int r_c[] = HEXNUM_C; + + printf("%s\t",status(compare(r_a,out_a,3))); hexputs(out_a,out_size_a); + printf("%s\t",status(compare(r_b,out_b,4))); hexputs(out_b,out_size_b); + printf("%s\t",status(compare(r_c,out_c,5))); hexputs(out_c,out_size_c); + + return 0; +} + +int hexputs(unsigned int* data, unsigned int len) { + int i; + for (i=0;i