123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
-
-
-
-
-
-
-
- #include "base64codec.hpp"
-
- using namespace std;
-
- namespace CodeDweller {
-
- namespace base64codec {
-
- const static char base64encode[65] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-
-
-
- const static unsigned char XXXX = 0xFF;
- const static unsigned char PAD0 = 0xFE;
- const static unsigned char IGNR = 0xFD;
- const static unsigned char STOP = 0xFC;
-
-
-
-
-
-
-
- const static unsigned char base64decode[256] = {
-
-
-
- XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,IGNR,IGNR,XXXX,XXXX,IGNR,XXXX,XXXX,
- XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,
- IGNR,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,0x3E,XXXX,XXXX,XXXX,0x3F,
- 0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,XXXX,XXXX,XXXX,PAD0,XXXX,XXXX,
- XXXX,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,
- 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,XXXX,XXXX,XXXX,XXXX,XXXX,
- XXXX,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
- 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,XXXX,XXXX,XXXX,XXXX,XXXX,
- XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,
- XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,
- XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,
- XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,
- XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,
- XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,
- XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,
- XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX,XXXX
- };
-
- }
-
- using namespace base64codec;
-
-
-
- void to_base64::convert(const unsigned char* bfr, const int len) {
- if(NULL == bfr || 0 >= len) {
- BadConversion = true;
- return;
- }
- int NewSize = (len / 3) * 4;
- if(0 < len % 3) NewSize += 4;
- reserve(NewSize);
- int cursor = 0;
- while(len > cursor) {
-
-
-
- enum EndGames {
- OneByte,
- TwoBytes,
- ThreeBytes
- } EndGame;
-
-
-
- unsigned long REGISTER = 0;
- REGISTER += bfr[cursor]; REGISTER <<= 8; ++cursor;
-
- EndGame = OneByte;
-
-
-
- if(len > cursor) {
- REGISTER += bfr[cursor];
- ++cursor;
-
- EndGame = TwoBytes;
- }
- REGISTER <<= 8;
-
-
-
- if(len > cursor) {
- REGISTER += bfr[cursor];
- ++cursor;
-
- EndGame = ThreeBytes;
-
- }
-
-
-
-
-
- const int SixBitMask = 0x0000003f;
- char code3 = base64encode[(REGISTER & SixBitMask)]; REGISTER >>= 6;
- char code2 = base64encode[(REGISTER & SixBitMask)]; REGISTER >>= 6;
- char code1 = base64encode[(REGISTER & SixBitMask)]; REGISTER >>= 6;
- char code0 = base64encode[(REGISTER & SixBitMask)];
-
- push_back(code0);
- push_back(code1);
-
- switch(EndGame) {
- case OneByte: {
- push_back('=');
- push_back('=');
- break;
- }
- case TwoBytes: {
- push_back(code2);
- push_back('=');
- break;
- }
- case ThreeBytes:
- default: {
- push_back(code2);
- push_back(code3);
- break;
- }
- }
- }
- BadConversion = false;
- }
-
- to_base64::to_base64(const vector<unsigned char>& bfr) :
- BadConversion(true) {
- convert(&bfr[0], bfr.size());
- }
-
- to_base64::to_base64(const vector<char>& bfr) :
- BadConversion(true) {
- convert(reinterpret_cast<const unsigned char*>(&bfr[0]), bfr.size());
- }
-
- to_base64::to_base64(const unsigned char* bfr, const int len) :
- BadConversion(true) {
- convert(bfr, len);
- }
-
-
- to_base64::to_base64(const char* bfr, const int len) :
- BadConversion(true) {
- convert(reinterpret_cast<const unsigned char*>(bfr), len);
- }
-
- to_base64::to_base64(const string& s) :
- BadConversion(true) {
- convert(reinterpret_cast<const unsigned char*>(s.c_str()), s.length());
- }
-
- to_base64::to_base64(const char* s) :
- BadConversion(true) {
- convert(reinterpret_cast<const unsigned char*>(s), strlen(s));
- }
-
- bool to_base64::Bad() {
- return BadConversion;
- }
-
-
-
- unsigned char from_base64::NextSixBits(
- int& cursor,
- const unsigned char* bfr,
- const int len) {
-
- while(len > cursor) {
- unsigned char c = base64decode[bfr[cursor]];
- ++cursor;
- if(IGNR == c) continue;
- if(XXXX == c) return c;
- return c;
- }
- return STOP;
- }
-
-
-
-
- void from_base64::convert(const unsigned char* bfr, const int len) {
- if(NULL == bfr || 0 >= len) { return; }
-
-
-
- int NewSize = len / 4 * 3;
- reserve(NewSize);
-
-
-
- int cursor = 0;
- while(len > cursor) {
-
- int REGISTER = 0;
- unsigned char LOOKUP = 0;
-
-
-
- const int MakeRoomFor6Bits = 6;
- LOOKUP = NextSixBits(cursor, bfr, len);
- if(STOP == LOOKUP) { break; }
- if(XXXX == LOOKUP) { return; }
- REGISTER += LOOKUP; REGISTER <<= MakeRoomFor6Bits;
-
- LOOKUP = NextSixBits(cursor, bfr, len);
- if(XXXX == LOOKUP || STOP == LOOKUP) { return; }
- REGISTER += LOOKUP;
-
-
-
- const int GetMS8OutOf12Bits = 4;
- const int BottomFourBits = 0x0000000F;
- push_back(REGISTER >> GetMS8OutOf12Bits);
- REGISTER = (REGISTER & BottomFourBits) << MakeRoomFor6Bits;
-
-
-
- LOOKUP = NextSixBits(cursor, bfr, len);
- if(XXXX == LOOKUP || STOP == LOOKUP) { return; }
- if(PAD0 == LOOKUP) { break; }
- REGISTER += LOOKUP;
-
-
-
- const int GetMS8OutOf10Bits = 2;
- const int BottomTwoBits = 0x00000003;
- push_back(REGISTER >> GetMS8OutOf10Bits);
- REGISTER = (REGISTER & BottomTwoBits) << MakeRoomFor6Bits;
-
- LOOKUP = NextSixBits(cursor, bfr, len);
- if(XXXX == LOOKUP || STOP == LOOKUP) { return; }
- if(PAD0 == LOOKUP) { break; }
- REGISTER += LOOKUP;
-
-
- push_back(REGISTER);
- }
- BadConversion = false;
- }
-
- from_base64::from_base64(const vector<unsigned char>& bfr) :
- BadConversion(true) {
- convert(&bfr[0], bfr.size());
- }
-
- from_base64::from_base64(const vector<char>& bfr) :
- BadConversion(true) {
- convert(reinterpret_cast<const unsigned char*>(&bfr[0]), bfr.size());
- }
-
- from_base64::from_base64(const string& s) :
- BadConversion(true) {
- convert(reinterpret_cast<const unsigned char*>(s.c_str()), s.length());
- }
-
- from_base64::from_base64(const char* s) :
- BadConversion(true) {
- convert(reinterpret_cast<const unsigned char*>(s), strlen(s));
- }
-
- bool from_base64::Bad() {
- return BadConversion;
- }
-
- }
|