From feaea470eb1daf5e3b82b8486db769b1cfc08d34 Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Tue, 6 Apr 2021 14:34:10 +0200 Subject: [PATCH] added initial code for Base64 encoding and decoding --- src/libgame/Makefile | 2 + src/libgame/base64.c | 190 +++++++++++++++++++++++++++++++++++++++++++ src/libgame/base64.h | 18 ++++ 3 files changed, 210 insertions(+) create mode 100644 src/libgame/base64.c create mode 100644 src/libgame/base64.h diff --git a/src/libgame/Makefile b/src/libgame/Makefile index 26f31160..0e2d57d6 100644 --- a/src/libgame/Makefile +++ b/src/libgame/Makefile @@ -22,6 +22,7 @@ SRCS = system.c \ image.c \ random.c \ hash.c \ + base64.c \ setup.c \ misc.c \ sdl.c \ @@ -39,6 +40,7 @@ OBJS = system.o \ image.o \ random.o \ hash.o \ + base64.o \ setup.o \ misc.o \ sdl.o \ diff --git a/src/libgame/base64.c b/src/libgame/base64.c new file mode 100644 index 00000000..7210900c --- /dev/null +++ b/src/libgame/base64.c @@ -0,0 +1,190 @@ +// ============================================================================ +// Artsoft Retro-Game Library +// ---------------------------------------------------------------------------- +// (c) 1995-2021 by Artsoft Entertainment +// Holger Schemel +// info@artsoft.org +// https://www.artsoft.org/ +// ---------------------------------------------------------------------------- +// base64.c +// ============================================================================ + +/* + + https://github.com/superwills/NibbleAndAHalf + base64.h -- Fast base64 encoding and decoding. + version 1.0.0, April 17, 2013 143a + + Copyright (C) 2013 William Sherif + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + William Sherif + will.sherif@gmail.com + + YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz + +*/ + +#include +#include + +#include "base64.h" + + +const static char* b64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ; + +// maps A=>0,B=>1.. +const static unsigned char unb64[]={ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //10 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //20 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //30 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //40 + 0, 0, 0, 62, 0, 0, 0, 63, 52, 53, //50 + 54, 55, 56, 57, 58, 59, 60, 61, 0, 0, //60 + 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, //70 + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, //80 + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, //90 + 25, 0, 0, 0, 0, 0, 0, 26, 27, 28, //100 + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, //110 + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, //120 + 49, 50, 51, 0, 0, 0, 0, 0, 0, 0, //130 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //140 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //150 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //160 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //170 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //180 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //190 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //200 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //210 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //220 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //230 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //240 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //250 + 0, 0, 0, 0, 0, 0, +}; // This array has 256 elements + +// Converts binary data of length=len to base64 characters. +// Length of the resultant string is stored in flen +// (you must pass pointer flen). +char* base64( const void* binaryData, int len, int *flen ) +{ + const unsigned char* bin = (const unsigned char*) binaryData ; + char* res ; + + int rc = 0 ; // result counter + int byteNo ; // I need this after the loop + + int modulusLen = len % 3 ; + int pad = ((modulusLen&1)<<1) + ((modulusLen&2)>>1) ; // 2 gives 1 and 1 gives 2, but 0 gives 0. + + *flen = 4*(len + pad)/3 ; + res = (char*) malloc( *flen + 1 ) ; // and one for the null + if( !res ) + { + puts( "ERROR: base64 could not allocate enough memory." ) ; + puts( "I must stop because I could not get enough" ) ; + return 0; + } + + for( byteNo = 0 ; byteNo <= len-3 ; byteNo+=3 ) + { + unsigned char BYTE0=bin[byteNo]; + unsigned char BYTE1=bin[byteNo+1]; + unsigned char BYTE2=bin[byteNo+2]; + res[rc++] = b64[ BYTE0 >> 2 ] ; + res[rc++] = b64[ ((0x3&BYTE0)<<4) + (BYTE1 >> 4) ] ; + res[rc++] = b64[ ((0x0f&BYTE1)<<2) + (BYTE2>>6) ] ; + res[rc++] = b64[ 0x3f&BYTE2 ] ; + } + + if( pad==2 ) + { + res[rc++] = b64[ bin[byteNo] >> 2 ] ; + res[rc++] = b64[ (0x3&bin[byteNo])<<4 ] ; + res[rc++] = '='; + res[rc++] = '='; + } + else if( pad==1 ) + { + res[rc++] = b64[ bin[byteNo] >> 2 ] ; + res[rc++] = b64[ ((0x3&bin[byteNo])<<4) + (bin[byteNo+1] >> 4) ] ; + res[rc++] = b64[ (0x0f&bin[byteNo+1])<<2 ] ; + res[rc++] = '='; + } + + res[rc]=0; // NULL TERMINATOR! ;) + return res ; +} + +unsigned char* unbase64( const char* ascii, int len, int *flen ) +{ + const unsigned char *safeAsciiPtr = (const unsigned char*)ascii ; + unsigned char *bin ; + int cb=0; + int charNo; + int pad = 0 ; + + if( len < 2 ) { // 2 accesses below would be OOB. + // catch empty string, return NULL as result. + puts( "ERROR: You passed an invalid base64 string (too short). You get NULL back." ) ; + *flen=0; + return 0 ; + } + if( safeAsciiPtr[ len-1 ]=='=' ) ++pad ; + if( safeAsciiPtr[ len-2 ]=='=' ) ++pad ; + + *flen = 3*len/4 - pad ; + bin = (unsigned char*)malloc( *flen ) ; + if( !bin ) + { + puts( "ERROR: unbase64 could not allocate enough memory." ) ; + puts( "I must stop because I could not get enough" ) ; + return 0; + } + + for( charNo=0; charNo <= len - 4 - pad ; charNo+=4 ) + { + int A=unb64[safeAsciiPtr[charNo]]; + int B=unb64[safeAsciiPtr[charNo+1]]; + int C=unb64[safeAsciiPtr[charNo+2]]; + int D=unb64[safeAsciiPtr[charNo+3]]; + + bin[cb++] = (A<<2) | (B>>4) ; + bin[cb++] = (B<<4) | (C>>2) ; + bin[cb++] = (C<<6) | (D) ; + } + + if( pad==1 ) + { + int A=unb64[safeAsciiPtr[charNo]]; + int B=unb64[safeAsciiPtr[charNo+1]]; + int C=unb64[safeAsciiPtr[charNo+2]]; + + bin[cb++] = (A<<2) | (B>>4) ; + bin[cb++] = (B<<4) | (C>>2) ; + } + else if( pad==2 ) + { + int A=unb64[safeAsciiPtr[charNo]]; + int B=unb64[safeAsciiPtr[charNo+1]]; + + bin[cb++] = (A<<2) | (B>>4) ; + } + + return bin ; +} diff --git a/src/libgame/base64.h b/src/libgame/base64.h new file mode 100644 index 00000000..beffe9ca --- /dev/null +++ b/src/libgame/base64.h @@ -0,0 +1,18 @@ +// ============================================================================ +// Artsoft Retro-Game Library +// ---------------------------------------------------------------------------- +// (c) 1995-2021 by Artsoft Entertainment +// Holger Schemel +// info@artsoft.org +// https://www.artsoft.org/ +// ---------------------------------------------------------------------------- +// base64.h +// ============================================================================ + +#ifndef BASE64_H +#define BASE64_H + +char* base64( const void* binaryData, int len, int *flen ); +unsigned char* unbase64( const char* ascii, int len, int *flen ); + +#endif -- 2.34.1