Base64.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <ndb_global.h>
  14. #include <Base64.hpp>
  15. static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  16.                              "abcdefghijklmnopqrstuvwxyz"
  17.                              "0123456789+/";
  18. int
  19. base64_encode(const UtilBuffer &src, BaseString &dst) {
  20.   const unsigned char *s = (const unsigned char *)src.get_data();
  21.   size_t i = 0;
  22.   size_t len = 0;
  23.   size_t src_len = src.length();
  24.   while(i < src_len) {
  25.     if(len == 76){
  26.       len = 0;
  27.       dst.append('n');
  28.     }
  29.     unsigned c;
  30.     c = s[i++];
  31.     c <<= 8;
  32.     if(i < src_len)
  33.       c += s[i];
  34.     c <<= 8;
  35.     i++;
  36.     
  37.     if(i < src_len)
  38.       c += s[i];
  39.     i++;
  40.     
  41.     dst.append(base64_table[(c >> 18) & 0x3f]);
  42.     dst.append(base64_table[(c >> 12) & 0x3f]);
  43.     if(i > (src_len + 1))
  44.       dst.append('=');
  45.     else
  46.       dst.append(base64_table[(c >> 6) & 0x3f]);
  47.     if(i > src_len)
  48.       dst.append('=');
  49.     else
  50.       dst.append(base64_table[(c >> 0) & 0x3f]);
  51.     len += 4;
  52.   }
  53.   return 0;
  54. }
  55. static inline unsigned
  56. pos(unsigned char c) {
  57.   return strchr(base64_table, c) - base64_table;
  58. }
  59. int
  60. base64_decode(const BaseString &src, UtilBuffer &dst) {
  61.   return base64_decode(src.c_str(), src.length(), dst);
  62. }
  63. #define SKIP_SPACE(src, i, size){     
  64.   while(i < size && isspace(* src)){  
  65.     i++;                              
  66.     src++;                            
  67.   }                                   
  68.   if(i == size){                      
  69.     i = size + 1;                     
  70.     break;                            
  71.   }                                   
  72. }
  73. int
  74. base64_decode(const char * src, size_t size, UtilBuffer &dst) {
  75.   size_t i = 0;
  76.   while(i < size){
  77.     unsigned c = 0;
  78.     int mark = 0;
  79.     SKIP_SPACE(src, i, size);
  80.     
  81.     c += pos(*src++);
  82.     c <<= 6;
  83.     i++;
  84.     SKIP_SPACE(src, i, size);
  85.     c += pos(*src++);
  86.     c <<= 6;
  87.     i++;
  88.     SKIP_SPACE(src, i, size);
  89.     if(* src != '=')
  90.       c += pos(*src++);
  91.     else {
  92.       i = size;
  93.       mark = 2;
  94.       c <<= 6;
  95.       goto end;
  96.     }
  97.     c <<= 6;
  98.     i++;
  99.     SKIP_SPACE(src, i, size);
  100.     if(*src != '=')
  101.       c += pos(*src++);
  102.     else {
  103.       i = size;
  104.       mark = 1;
  105.       goto end;
  106.     }
  107.     i++;
  108.   end:
  109.     char b[3];
  110.     b[0] = (c >> 16) & 0xff;
  111.     b[1] = (c >>  8) & 0xff;
  112.     b[2] = (c >>  0) & 0xff;
  113.     
  114.     dst.append((void *)b, 3-mark);
  115.   }
  116.   
  117.   if(i != size){
  118.     abort();
  119.     return -1;
  120.   }
  121.   return 0;
  122. }
  123. #ifdef __TEST__B64
  124. /**
  125.  * USER_FLAGS="-D__TEST__B64" make Base64.o && g++ Base64.o BaseString.o
  126.  */
  127. inline
  128. void
  129. require(bool b){
  130.   if(!b)
  131.     abort();
  132. }
  133. int
  134. main(void){
  135.   for(int i = 0; i < 500; i++){
  136.     const size_t len = rand() % 10000 + 1;
  137.     UtilBuffer src;
  138.     for(size_t j = 0; j<len; j++){
  139.       char c = rand();
  140.       src.append(&c, 1);
  141.     }
  142.     require(src.length() == len);
  143.     BaseString str;
  144.     require(base64_encode(src, str) == 0);
  145.     if(str.length() == 3850){
  146.       printf(">%s<n", str.c_str());
  147.     }
  148.     UtilBuffer dst;
  149.     require(base64_decode(str, dst) == 0);
  150.     require(dst.length() == src.length());
  151.     const char * c_src = (char*)src.get_data();
  152.     const char * c_dst = (char*)dst.get_data();
  153.     if(memcmp(src.get_data(), dst.get_data(), src.length()) != 0){
  154.       printf("-- src --n");
  155.       for(int i2 = 0; i2<len; i2++){
  156. unsigned char c = c_src[i2];
  157. printf("%.2x ", (unsigned)c);
  158. if((i2 % 8) == 7)
  159.   printf("n");
  160.       }
  161.       printf("n");
  162.       printf("-- dst --n");
  163.       for(int i2 = 0; i2<len; i2++){
  164. unsigned char c = c_dst[i2];
  165. printf("%.2x ", (unsigned)c);
  166. if((i2 % 8) == 7)
  167.   printf("n");
  168.       }
  169.       printf("n");
  170.       abort();
  171.     }
  172.   }
  173.   return 0;
  174. }
  175. #endif