123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- /************************************************
- * *
- * CBase64.cpp *
- * Base 64 de- and encoding class *
- * *
- * ============================================ *
- * *
- * This class was written on 28.05.2003 *
- * by Jan Raddatz [jan-raddatz@web.de] *
- * *
- * ============================================ *
- * *
- * Copyright (c) by Jan Raddatz *
- * This class was published @ codeguru.com *
- * 28.05.2003 *
- * *
- ************************************************/
- #include "pch.h"
- #include "Base64.h"
- char CBase64Coder::ch64[] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
- 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
- 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '='
- };
- CBase64Coder::CBase64Coder()
- {
- buf = NULL;
- size = 0;
- }
- CBase64Coder::~CBase64Coder()
- {
- if (buf)
- {
- free(buf);
- buf = NULL;
- }
- }
- void CBase64Coder::allocMem(int NewSize)
- {
- if (buf)
- buf = (char*)realloc(buf, NewSize);
- else
- buf = (char*)malloc(NewSize);
- memset(buf, 0, NewSize);
- }
- const char* CBase64Coder::encode(const string& buffer)
- {
- return encode(buffer.c_str(), buffer.length());
- }
- const char* CBase64Coder::encode(const char* buffer, int buflen)
- {
- #ifdef _DEBUG
- DWORD start, finish;
- start = GetTickCount();
- #endif
- int nLeft = 3 - buflen % 3;
- //根据BASE64算法,总长度会变成原来的4/3倍
- //所以内存分配=length*4/3并加1位作为结束符号(0)
- size = calc_base64_len(buflen);
- allocMem(size + 1);
- //临时变量,
- int index = 0;
- char *pOut = buf;
- while (buflen - index >= 3)
- {
- const char * p1 = buffer + index;
- const char * p2 = p1 + 1;
- const char * p3 = p2 + 1;
- char c1 = ((*p1) & (0xFC)) >> 2;
- char c2 = ((*p1) & (0x03)) << 4 | ((*p2) & 0xF0) >> 4;
- char c3 = ((*p2) & (0x0F)) << 2 | ((*p3) & 0xC0) >> 6;
- char c4 = (*p3) & (0x3F);
- *(pOut++) = _getBase64Char(c1);
- *(pOut++) = _getBase64Char(c2);
- *(pOut++) = _getBase64Char(c3);
- *(pOut++) = _getBase64Char(c4);
- index += 3;
- }
- int last = buflen - index;
- if (last == 1)
- {
- const char * p1 = buffer + index;
- char c1 = ((*p1) & (0xFC)) >> 2;
- char c2 = ((*p1) & (0x03)) << 4;
- *(pOut++) = _getBase64Char(c1);
- *(pOut++) = _getBase64Char(c2);
- *(pOut++) = '=';
- *(pOut++) = '=';
- }
- else if (last == 2)
- {
- const char * p1 = buffer + index;
- const char * p2 = p1 + 1;
- char c1 = ((*p1) & (0xFC)) >> 2;
- char c2 = ((*p1) & (0x03)) << 4 | ((*p2) & 0xF0) >> 4;
- char c3 = ((*p2) & (0x0F)) << 2;
- *(pOut++) = _getBase64Char(c1);
- *(pOut++) = _getBase64Char(c2);
- *(pOut++) = _getBase64Char(c3);
- *(pOut++) = '=';
- //*(pOut++)='=';
- }
- #ifdef _DEBUG
- finish = GetTickCount();
- //TRACE("func Base64Encode spend %d ms\n", finish - start);
- #endif
- return buf;
- }
- const char* CBase64Coder::decode(const char* buffer, int Length)
- {
- #ifdef _DEBUG
- DWORD start, finish;
- start = GetTickCount();
- #endif
- int length = Length;
- if (length % 4 != 0)
- return NULL;
- int nLen = calc_data_len(buffer,Length);
- size = nLen;
- allocMem(size + 1);
- int dec = 0;
- while (buffer[Length - 1 - dec] == '=')
- {
- dec++;
- }
- int real_len = length - dec;
- int index = 0;
- char *pOut = buf;
- while (real_len - index >= 4)
- {
- const char * p1 = buffer + index;
- const char * p2 = p1 + 1;
- const char * p3 = p2 + 1;
- const char * p4 = p3 + 1;
- char c1 = BinSearch(*p1);
- if (c1 == -1)
- {
- return NULL;
- }
- char c2 = BinSearch(*p2);
- if (c2 == -1)
- {
- return NULL;
- }
- char c3 = BinSearch(*p3);
- if (c3 == -1)
- {
- return NULL;
- }
- char c4 = BinSearch(*p4);
- if (c4 == -1)
- {
- return NULL;
- }
-
- *(pOut++) = (c1) << 2 | ((c2)&(0x30)) >> 4;
- *(pOut++) = ((c2)&(0xF)) << 4 | ((c3)&(0x3C)) >> 2;
- *(pOut++) = ((c3)&(0x03)) << 6 | (c4)&(0x3F);
- index += 4;
- }
- int last = real_len - index;
- if (last == 2)
- {
- const char * p1 = buffer + index;
- const char * p2 = p1 + 1;
- char c1 = BinSearch(*p1);
- char c2 = BinSearch(*p2);
- *(pOut++) = (c1) << 2 | ((c2)&(0x30)) >> 4;
- }
- else if (last == 3)
- {
- const char * p1 = buffer + index;
- const char * p2 = p1 + 1;
- const char * p3 = p2 + 1;
- char c1 = BinSearch(*p1);
- char c2 = BinSearch(*p2);
- char c3 = BinSearch(*p3);
- *(pOut++) = (c1) << 2 | ((c2)&(0x30)) >> 4;
- *(pOut++) = ((c2)&(0x0F)) << 4 | ((c3)&(0x30)) >> 2;
- }
- #ifdef _DEBUG
- finish = GetTickCount();
- TRACE("func Base64Decode spend %d ms\n", finish - start);
- #endif
- return buf;
- }
- //采用二分法查找p在ch64数组中的位置,并返回。如果找不到则返回-1
- int CBase64Coder::BinSearch(char p)
- {
- /*if (p >= 'A' && p <= 'Z')
- return (p - 'A');
- else if (p >= 'a' && p <= 'z')
- return (p - 'a' + 26);
- else if (p >= '0' && p <= '9')
- return (p - '0' + 26 + 26);
- else if (p == '+')
- return 62;
- else if (p == '/')
- return 63;
- else if (p == '=')
- return 64;*/
- switch (p)
- {
- case 'A':
- case 'B':
- case 'C':
- case 'D':
- case 'E':
- case 'F':
- case 'G':
- case 'H':
- case 'I':
- case 'J':
- case 'K':
- case 'L':
- case 'M':
- case 'N':
- case 'O':
- case 'P':
- case 'Q':
- case 'R':
- case 'S':
- case 'T':
- case 'U':
- case 'V':
- case 'W':
- case 'X':
- case 'Y':
- case 'Z':
- return p - 'A';
- case 'a':
- case 'b':
- case 'c':
- case 'd':
- case 'e':
- case 'f':
- case 'g':
- case 'h':
- case 'i':
- case 'j':
- case 'k':
- case 'l':
- case 'm':
- case 'n':
- case 'o':
- case 'p':
- case 'q':
- case 'r':
- case 's':
- case 't':
- case 'u':
- case 'v':
- case 'w':
- case 'x':
- case 'y':
- case 'z':
- return p - 'a' + 26;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- return p - '0' + 52;
- case '+':
- return 62;
- case '/':
- return 63;
- case '=':
- return 64;
- }
- return -1;
- }
- int CBase64Coder::calc_base64_len(int data_len)
- {
- int last = data_len * 8 % 6;
- if (last == 0)
- {
- return data_len * 8 / 6;
- }
- else
- {
- int base64_len = data_len * 8 / 6 + 1;
- base64_len += (last == 2 ? 2 : 1);
- return base64_len;
- }
- }
- int CBase64Coder::calc_data_len(const char * base64, int base64_len)
- {
- int dec = 0;
- while (base64[base64_len - 1 - dec] == '=')
- {
- dec++;
- }
- return ((base64_len - dec) * 6) / 8;
- }
- char CBase64Coder::_getBase64Char(char c)
- {
- return ch64[c];
- }
|