00001 // Base64.h 00002 00003 #ifndef BASE64_H 00004 #define BASE64_H 00005 00006 #include <stdint.h> 00007 #include <string> 00008 #include <vector> 00009 #include <stdexcept> 00010 00011 namespace Yosokumo 00012 { 00013 00014 /** 00015 * Provides methods for converting bytes sequences to Base64 character strings 00016 * and vice versa. 00017 * 00018 * <ul> 00019 * <li><code>static void encodeBytes(const std::vector<uint8_t> &source, std::string &dest)</code> 00020 * <li><code>static void decodeString(const std::string &source, std::vector<uint8_t> &dest)</code> 00021 * </ul> 00022 * 00023 * Be aware that there is not a one-to-one correspondence between byte 00024 * sequences and Base64 character sequences. Given any character sequence C 00025 * created by <code>encodeBytes</code>, the call <code>decodeString(C)</code> 00026 * will return the original byte sequence. However, there exist character 00027 * sequences which are never produced by <code>encodeBytes</code>, and, hence, 00028 * applying <code>decodeString</code> to such character sequences produces 00029 * byte sequences from which the original character sequences cannot be 00030 * recovered. For example, <code>decodeString</code> converts both AA== and 00031 * AB== to the single byte 0, and <code>encodeBytes</code> converts the 00032 * single byte 0 to AA==. There does not exist a sequence of bytes which 00033 * will cause <code>encodeBytes</code> to return AB==. 00034 * 00035 * @author Roger House 00036 * @version 0.9 00037 */ 00038 00039 class Base64 00040 { 00041 /** 00042 * Base64 character set: A-Z, a-z, 0-9, +, /. 00043 **/ 00044 00045 static char encode64[]; 00046 00047 /** 00048 * Convert a sequence of three bytes to a sequence of four characters. 00049 * 00050 * Map three 8-bit bytes to four 6-bit bytes: 00051 * 00052 *<pre> 00053 * 765432 10 7654 3210 76 543210 00054 * +---------+---------+---------+ 00055 * |AAAAAA AA|BBBB BBBB|CC CCCCCC| 00056 * +------+-------+-------+------+ 00057 * |aaaaaa|bb bbbb|cccc cc|dddddd| 00058 * +------+-------+-------+------+ 00059 * 543210 54 3210 5432 10 543210 00060 *</pre> 00061 * 00062 * @param A the first byte. 00063 * @param B the second byte. 00064 * @param C the third byte. 00065 * @param abcd the resulting four characters are appended to abcd. 00066 */ 00067 00068 static void map3to4(uint8_t A, uint8_t B, uint8_t C, std::string &abcd); 00069 00070 public: 00071 00072 /** 00073 * Convert a sequence of bytes to a Base64 string. 00074 * 00075 * @param source is the input to this function, a sequence of zero or 00076 * more 8-bit bytes. 00077 * @param dest is the output from this function, a string containing 00078 * the Base64 representation of the input bytes, 6-bits per 00079 * character. 00080 */ 00081 00082 static void encodeBytes( 00083 const std::vector<uint8_t> &source, 00084 std::string &dest); 00085 00086 /** 00087 * Convert a 6-bit Base64 character to an 8-bit byte. 00088 * 00089 * @param c a 6-bit Base64 character. 00090 * @return the 8-bit byte corresponding to the input character. 00091 * @throws std::invalid_argument if the input character is not a 00092 * Base64 character. 00093 */ 00094 00095 static uint8_t decode64(char c) throw(std::invalid_argument); 00096 00097 private: 00098 00099 /** 00100 * Convert a sequence of four characters to a sequence of three bytes. 00101 * See the comment for map3to4 for the exact mapping. 00102 * 00103 * @param a the first character. 00104 * @param b the second character. 00105 * @param c the third character. 00106 * @param d the fourth character. 00107 * @param ABC the resulting three bytes are stored here. 00108 * @param j an index to the first byte in ABC to change. 00109 * @param n 1, 2, or 3, indicating how many bytes to store in ABC. 00110 * @throws std::invalid_argument if any input character is not a 00111 * Base64 character. 00112 */ 00113 00114 static void map4to3( 00115 char a, char b, char c, char d, 00116 std::vector<uint8_t> &ABC, int j, 00117 int n) throw(std::invalid_argument); 00118 00119 public: 00120 00121 /** 00122 * Convert a Base64 string to a sequence of bytes. 00123 * 00124 * @param source is the input to this function, a string of zero or 00125 * more 6-bit Base64 characters. 00126 * @param dest is the output from this function, a a byte sequence 00127 * containing the 8-bit bytes corresponding to the input 00128 * characters. 00129 * @throws std::invalid_argument if the length of the input string is 00130 * not a multiple of four. 00131 * @throws std::invalid_argument if the input string contains a 00132 * character which is not a Base64 character. 00133 */ 00134 00135 static void decodeString( 00136 const std::string &source, 00137 std::vector<uint8_t> &dest) throw(std::invalid_argument); 00138 00139 }; // end class Base64 00140 00141 } // end namespace Yosokumo 00142 00143 #endif // BASE64_H 00144 00145 // end Base64.h