base64.cc (3662B)
1 /* -*- Mode: c++; -*- */ 2 /* -------------------------------------------------------------------- 3 * Filename: 4 * base64.cc 5 * 6 * Description: 7 * Implementation of base64 Utilities 8 * 9 * Authors: 10 * Andreas Aardal Hanssen <andreas-binc curly bincimap spot org> 11 * 12 * Bugs: 13 * 14 * ChangeLog: 15 * 16 * -------------------------------------------------------------------- 17 * Copyright 2002-2005 Andreas Aardal Hanssen 18 * 19 * This program is free software; you can redistribute it and/or modify 20 * it under the terms of the GNU General Public License as published by 21 * the Free Software Foundation; either version 2 of the License, or 22 * (at your option) any later version. 23 * 24 * This program is distributed in the hope that it will be useful, 25 * but WITHOUT ANY WARRANTY; without even the implied warranty of 26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 * GNU General Public License for more details. 28 * 29 * You should have received a copy of the GNU General Public License 30 * along with this program; if not, write to the Free Software 31 * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. 32 * -------------------------------------------------------------------- 33 */ 34 #ifdef HAVE_CONFIG_H 35 #include <config.h> 36 #endif 37 38 #include "base64.h" 39 #include <string> 40 #include <iostream> 41 42 using ::std::string; 43 44 typedef unsigned char byte; /* Byte type */ 45 46 #define TRUE 1 47 #define FALSE 0 48 49 #define LINELEN 72 /* Encoded line length (max 76) */ 50 51 static byte dtable[256]; 52 53 string Binc::base64encode(const string &s_in) 54 { 55 int i; 56 string result; 57 58 /* Fill dtable with character encodings. */ 59 60 for (i = 0; i < 26; i++) { 61 dtable[i] = 'A' + i; 62 dtable[26 + i] = 'a' + i; 63 } 64 for (i = 0; i < 10; i++) { 65 dtable[52 + i] = '0' + i; 66 } 67 dtable[62] = '+'; 68 dtable[63] = '/'; 69 70 string::const_iterator s_i = s_in.begin(); 71 while (s_i != s_in.end()) { 72 73 byte igroup[3], ogroup[4]; 74 int c, n; 75 76 igroup[0] = igroup[1] = igroup[2] = 0; 77 for (n = 0; n < 3 && s_i != s_in.end(); n++) { 78 c = *s_i++; 79 igroup[n] = (byte) c; 80 } 81 if (n > 0) { 82 ogroup[0] = dtable[igroup[0] >> 2]; 83 ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; 84 ogroup[2] = dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; 85 ogroup[3] = dtable[igroup[2] & 0x3F]; 86 87 /* Replace characters in output stream with "=" pad 88 characters if fewer than three characters were 89 read from the end of the input stream. */ 90 91 if (n < 3) { 92 ogroup[3] = '='; 93 if (n < 2) { 94 ogroup[2] = '='; 95 } 96 } 97 98 for (i = 0; i < 4; i++) 99 result += ogroup[i]; 100 } 101 } 102 103 return result; 104 } 105 106 string Binc::base64decode(const string &s_in) 107 { 108 string result; 109 int i; 110 111 for (i = 0; i < 255; i++) { 112 dtable[i] = 0x80; 113 } 114 for (i = 'A'; i <= 'Z'; i++) { 115 dtable[i] = 0 + (i - 'A'); 116 } 117 for (i = 'a'; i <= 'z'; i++) { 118 dtable[i] = 26 + (i - 'a'); 119 } 120 for (i = '0'; i <= '9'; i++) { 121 dtable[i] = 52 + (i - '0'); 122 } 123 dtable[(int) '+'] = 62; 124 dtable[(int) '/'] = 63; 125 dtable[(int) '='] = 0; 126 127 /*CONSTANTCONDITION*/ 128 string::const_iterator s_i = s_in.begin(); 129 while (s_i != s_in.end()) { 130 byte a[4], b[4], o[3]; 131 132 for (i = 0; i < 4 && s_i != s_in.end(); i++) { 133 int c = *s_i++; 134 135 if (dtable[c] & 0x80) 136 return result; 137 138 a[i] = (byte) c; 139 b[i] = (byte) dtable[c]; 140 } 141 142 o[0] = (b[0] << 2) | (b[1] >> 4); 143 o[1] = (b[1] << 4) | (b[2] >> 2); 144 o[2] = (b[2] << 6) | b[3]; 145 146 i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3); 147 148 for (int j = 0; j < i; ++j) 149 result += o[j]; 150 151 if (i < 3) 152 break; 153 } 154 155 return result; 156 }