日历
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
31 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
|
统计
- 随笔 - 58
- 文章 - 0
- 评论 - 55
- 引用 - 0
导航
常用链接
留言簿(3)
随笔分类(58)
随笔档案(58)
搜索
最新评论
阅读排行榜
评论排行榜
|
/**//* *Base64Coder.h */ #ifndef BASE64CODER_H #define BASE64CODER_H
#include <string.h>
#ifdef __BORLANDC__ #define Boolean bool #define False false #define True true #else
typedef unsigned Boolean; #ifndef False const Boolean False = 0; #endif #ifndef True const Boolean True = 1; #endif
#endif
class Base64Coder { public: Base64Coder(); ~Base64Coder();
char* Base64Encode(char const* origSigned, unsigned origLength); unsigned char* Base64Decode(char* in, unsigned& resultSize,Boolean trimTrailingZeros);
private: Boolean haveInitedBase64DecodeTable; void initBase64DecodeTable(); char* strDupSize(char const* str); char base64DecodeTable[256]; char base64Char[64]; }; #endif
/**//* *Base64Coder.cpp */ #include "Base64Coder.h"
Base64Coder::Base64Coder() { int i,j=0; for (i = 'A'; i <= 'Z'; ++i) base64Char[j++] = i; for (i = 'a'; i <= 'z'; ++i) base64Char[j++] = i; for (i = '0'; i <= '9'; ++i) base64Char[j++] = i; base64Char[j++] = '+'; base64Char[j++] = '/';
haveInitedBase64DecodeTable=False; }
Base64Coder::~Base64Coder() {
}
void Base64Coder::initBase64DecodeTable() { int i; for (i = 0; i < 256; ++i) base64DecodeTable[i] = (char)0x80; // default value: invalid
for (i = 'A'; i <= 'Z'; ++i) base64DecodeTable[i] = 0 + (i - 'A'); for (i = 'a'; i <= 'z'; ++i) base64DecodeTable[i] = 26 + (i - 'a'); for (i = '0'; i <= '9'; ++i) base64DecodeTable[i] = 52 + (i - '0'); base64DecodeTable[(unsigned char)'+'] = 62; base64DecodeTable[(unsigned char)'/'] = 63; base64DecodeTable[(unsigned char)'='] = 0; }
unsigned char* Base64Coder::Base64Decode(char* in, unsigned& resultSize,Boolean trimTrailingZeros) { if (!haveInitedBase64DecodeTable) { initBase64DecodeTable(); haveInitedBase64DecodeTable = True; }
unsigned char* out = (unsigned char*)strDupSize(in); // ensures we have enough space int k = 0; int const jMax = strlen(in) - 3; // in case "in" is not a multiple of 4 bytes (although it should be) for (int j = 0; j < jMax; j += 4) { char inTmp[4], outTmp[4]; for (int i = 0; i < 4; ++i) { inTmp[i] = in[i+j]; outTmp[i] = base64DecodeTable[(unsigned char)inTmp[i]]; if ((outTmp[i]&0x80) != 0) outTmp[i] = 0; // pretend the input was 'A' }
out[k++] = (outTmp[0]<<2) | (outTmp[1]>>4); out[k++] = (outTmp[1]<<4) | (outTmp[2]>>2); out[k++] = (outTmp[2]<<6) | outTmp[3]; }
if (trimTrailingZeros) { while (k > 0 && out[k-1] == '\0') --k; } resultSize = k; unsigned char* result = new unsigned char[resultSize]; memmove(result, out, resultSize); delete[] out;
return result; }
char* Base64Coder::Base64Encode(char const* origSigned, unsigned origLength) { unsigned char const* orig = (unsigned char const*)origSigned; // in case any input bytes have the MSB set if (orig == NULL) return NULL;
unsigned const numOrig24BitValues = origLength/3; Boolean havePadding = origLength > numOrig24BitValues*3; Boolean havePadding2 = origLength == numOrig24BitValues*3 + 2; unsigned const numResultBytes = 4*(numOrig24BitValues + havePadding); char* result = new char[numResultBytes+1]; // allow for trailing '\0'
// Map each full group of 3 input bytes into 4 output base-64 characters: unsigned i; for (i = 0; i < numOrig24BitValues; ++i) { result[4*i+0] = base64Char[(orig[3*i]>>2)&0x3F]; result[4*i+1] = base64Char[(((orig[3*i]&0x3)<<4) | (orig[3*i+1]>>4))&0x3F]; result[4*i+2] = base64Char[((orig[3*i+1]<<2) | (orig[3*i+2]>>6))&0x3F]; result[4*i+3] = base64Char[orig[3*i+2]&0x3F]; }
// Now, take padding into account. (Note: i == numOrig24BitValues) if (havePadding) { result[4*i+0] = base64Char[(orig[3*i]>>2)&0x3F]; if (havePadding2) { result[4*i+1] = base64Char[(((orig[3*i]&0x3)<<4) | (orig[3*i+1]>>4))&0x3F]; result[4*i+2] = base64Char[(orig[3*i+1]<<2)&0x3F]; } else { result[4*i+1] = base64Char[((orig[3*i]&0x3)<<4)&0x3F]; result[4*i+2] = '='; } result[4*i+3] = '='; }
result[numResultBytes] = '\0'; return result; }
char* Base64Coder::strDupSize(char const* str) { if (str == NULL) return NULL; int len = strlen(str) + 1; char* copy = new char[len];
return copy; }
下面是测试程序:
/**//* *main.cpp */ #include "Base64Coder.h"
#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
int main(void) { int i; Base64Coder * p_Base64Coder=new Base64Coder(); struct test { unsigned char *data; char *encoded_ref; } tests[] = { {(unsigned char*)"", ""}, {(unsigned char*)"1", "MQ=="}, {(unsigned char*)"22", "MjI="}, {(unsigned char*)"333", "MzMz"}, {(unsigned char*)"4444", "NDQ0NA=="}, {(unsigned char*)"55555", "NTU1NTU="}, {(unsigned char*)"666666", "NjY2NjY2"}, {(unsigned char*)"abc:def", "YWJjOmRlZg=="}, };
printf("Encoding/decoding tests\n"); for (i = 0; i < FF_ARRAY_ELEMS(tests); i++) { unsigned char * res; unsigned length; res=p_Base64Coder->Base64Decode(tests[i].encoded_ref,length,True); if (strcmp((char *)res,(char *)tests[i].data)!=0) { printf("Passed! "); } else { printf("Failed! "); } for (int j=0;j<length;j++) { printf("%c",res[j]); } printf(" Length:%d\n",length); printf("\n"); } return 0; }
开始时不小心,以为ffmpeg的Base64解码不正确,就用了Live555的,后来发现ffmpeg的其实也是正确的。 Live555的Decode函数最后的参数trimTrailingZeros设置成True就和ffmpeg的Base64一样了,意为将尾部的0去掉。 可以将上面测试程序中的True改成False,然后看打印出来的结果就明白了(打印的尾部0是看不到的)。
|