Base64.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:4k
- /* Copyright (C) 2003 MySQL AB
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
- #include <ndb_global.h>
- #include <Base64.hpp>
- static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789+/";
- int
- base64_encode(const UtilBuffer &src, BaseString &dst) {
- const unsigned char *s = (const unsigned char *)src.get_data();
- size_t i = 0;
- size_t len = 0;
- size_t src_len = src.length();
- while(i < src_len) {
- if(len == 76){
- len = 0;
- dst.append('n');
- }
- unsigned c;
- c = s[i++];
- c <<= 8;
- if(i < src_len)
- c += s[i];
- c <<= 8;
- i++;
-
- if(i < src_len)
- c += s[i];
- i++;
-
- dst.append(base64_table[(c >> 18) & 0x3f]);
- dst.append(base64_table[(c >> 12) & 0x3f]);
- if(i > (src_len + 1))
- dst.append('=');
- else
- dst.append(base64_table[(c >> 6) & 0x3f]);
- if(i > src_len)
- dst.append('=');
- else
- dst.append(base64_table[(c >> 0) & 0x3f]);
- len += 4;
- }
- return 0;
- }
- static inline unsigned
- pos(unsigned char c) {
- return strchr(base64_table, c) - base64_table;
- }
- int
- base64_decode(const BaseString &src, UtilBuffer &dst) {
- return base64_decode(src.c_str(), src.length(), dst);
- }
- #define SKIP_SPACE(src, i, size){
- while(i < size && isspace(* src)){
- i++;
- src++;
- }
- if(i == size){
- i = size + 1;
- break;
- }
- }
- int
- base64_decode(const char * src, size_t size, UtilBuffer &dst) {
- size_t i = 0;
- while(i < size){
- unsigned c = 0;
- int mark = 0;
- SKIP_SPACE(src, i, size);
-
- c += pos(*src++);
- c <<= 6;
- i++;
- SKIP_SPACE(src, i, size);
- c += pos(*src++);
- c <<= 6;
- i++;
- SKIP_SPACE(src, i, size);
- if(* src != '=')
- c += pos(*src++);
- else {
- i = size;
- mark = 2;
- c <<= 6;
- goto end;
- }
- c <<= 6;
- i++;
- SKIP_SPACE(src, i, size);
- if(*src != '=')
- c += pos(*src++);
- else {
- i = size;
- mark = 1;
- goto end;
- }
- i++;
- end:
- char b[3];
- b[0] = (c >> 16) & 0xff;
- b[1] = (c >> 8) & 0xff;
- b[2] = (c >> 0) & 0xff;
-
- dst.append((void *)b, 3-mark);
- }
-
- if(i != size){
- abort();
- return -1;
- }
- return 0;
- }
- #ifdef __TEST__B64
- /**
- * USER_FLAGS="-D__TEST__B64" make Base64.o && g++ Base64.o BaseString.o
- */
- inline
- void
- require(bool b){
- if(!b)
- abort();
- }
- int
- main(void){
- for(int i = 0; i < 500; i++){
- const size_t len = rand() % 10000 + 1;
- UtilBuffer src;
- for(size_t j = 0; j<len; j++){
- char c = rand();
- src.append(&c, 1);
- }
- require(src.length() == len);
- BaseString str;
- require(base64_encode(src, str) == 0);
- if(str.length() == 3850){
- printf(">%s<n", str.c_str());
- }
- UtilBuffer dst;
- require(base64_decode(str, dst) == 0);
- require(dst.length() == src.length());
- const char * c_src = (char*)src.get_data();
- const char * c_dst = (char*)dst.get_data();
- if(memcmp(src.get_data(), dst.get_data(), src.length()) != 0){
- printf("-- src --n");
- for(int i2 = 0; i2<len; i2++){
- unsigned char c = c_src[i2];
- printf("%.2x ", (unsigned)c);
- if((i2 % 8) == 7)
- printf("n");
- }
- printf("n");
- printf("-- dst --n");
- for(int i2 = 0; i2<len; i2++){
- unsigned char c = c_dst[i2];
- printf("%.2x ", (unsigned)c);
- if((i2 % 8) == 7)
- printf("n");
- }
- printf("n");
- abort();
- }
- }
- return 0;
- }
- #endif