MACE  1.0.0
 All Classes Namespaces Files Functions Variables Enumerations Defines
libs/rpc/include/mace/rpc/base64.hpp
00001 #ifndef _MACE_RPC_BASE64_HPP
00002 #define _MACE_RPC_BASE64_HPP
00003 /* 
00004    base64.cpp and base64.h
00005 
00006    Copyright (C) 2004-2008 René Nyffenegger
00007 
00008    This source code is provided 'as-is', without any express or implied
00009    warranty. In no event will the author be held liable for any damages
00010    arising from the use of this software.
00011 
00012    Permission is granted to anyone to use this software for any purpose,
00013    including commercial applications, and to alter it and redistribute it
00014    freely, subject to the following restrictions:
00015 
00016    1. The origin of this source code must not be misrepresented; you must not
00017       claim that you wrote the original source code. If you use this source code
00018       in a product, an acknowledgment in the product documentation would be
00019       appreciated but is not required.
00020 
00021    2. Altered source versions must be plainly marked as such, and must not be
00022       misrepresented as being the original source code.
00023 
00024    3. This notice may not be removed or altered from any source distribution.
00025 
00026    René Nyffenegger rene.nyffenegger@adp-gmbh.ch
00027 
00028 */
00029 
00030 #include <iostream>
00031 #include <sstream>
00032 
00033 namespace mace { namespace rpc {
00034 
00035 inline const std::string& base64_chars()
00036 {
00037     static const std::string m_base64_chars = 
00038                  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
00039                  "abcdefghijklmnopqrstuvwxyz"
00040                  "0123456789+/";
00041     return m_base64_chars;
00042 }
00043 
00044 static inline bool is_base64(unsigned char c) {
00045   return (isalnum(c) || (c == '+') || (c == '/'));
00046 }
00047 
00048 inline std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len);
00049 
00050 inline std::string base64_encode( const std::string& enc ) {
00051   char const* s = enc.c_str();
00052   return base64_encode( (unsigned char const*)s, enc.size() );
00053 }
00054 inline std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
00055 
00056   std::string ret;
00057   int i = 0;
00058   int j = 0;
00059   unsigned char char_array_3[3];
00060   unsigned char char_array_4[4];
00061 
00062   while (in_len--) {
00063     char_array_3[i++] = *(bytes_to_encode++);
00064     if (i == 3) {
00065       char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
00066       char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
00067       char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
00068       char_array_4[3] = char_array_3[2] & 0x3f;
00069 
00070       for(i = 0; (i <4) ; i++)
00071         ret += base64_chars()[char_array_4[i]];
00072       i = 0;
00073     }
00074   }
00075 
00076   if (i)
00077   {
00078     for(j = i; j < 3; j++)
00079       char_array_3[j] = '\0';
00080 
00081     char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
00082     char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
00083     char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
00084     char_array_4[3] = char_array_3[2] & 0x3f;
00085 
00086     for (j = 0; (j < i + 1); j++)
00087       ret += base64_chars()[char_array_4[j]];
00088 
00089     while((i++ < 3))
00090       ret += '=';
00091 
00092   }
00093 
00094   return ret;
00095 
00096 }
00097 
00098 
00099 inline std::string base64_decode(std::string const& encoded_string) {
00100 
00101 
00102   int in_len = encoded_string.size();
00103   int i = 0;
00104   int j = 0;
00105   int in_ = 0;
00106   unsigned char char_array_4[4], char_array_3[3];
00107   std::string ret;
00108 
00109   while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
00110     char_array_4[i++] = encoded_string[in_]; in_++;
00111     if (i ==4) {
00112       for (i = 0; i <4; i++)
00113         char_array_4[i] = base64_chars().find(char_array_4[i]);
00114 
00115       char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
00116       char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
00117       char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
00118 
00119       for (i = 0; (i < 3); i++)
00120         ret += char_array_3[i];
00121       i = 0;
00122     }
00123   }
00124 
00125   if (i) {
00126     for (j = i; j <4; j++)
00127       char_array_4[j] = 0;
00128 
00129     for (j = 0; j <4; j++)
00130       char_array_4[j] = base64_chars().find(char_array_4[j]);
00131 
00132     char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
00133     char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
00134     char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
00135 
00136     for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
00137   }
00138 
00139   return ret;
00140 }
00141 
00142 
00143 template<typename T>
00144 std::string to_base64( const T& v ) {
00145   std::stringstream ss; ss << v;
00146   return base64_encode(ss.str());
00147 }
00148 
00149 template<typename T>
00150 T from_base64( const std::string& str ) {
00151   T v;
00152   std::stringstream ss(base64_decode( str ));
00153   ss >> v;
00154   return v;
00155 }
00156 
00157 template<typename T>
00158 void from_base64( const std::string& b64, T& v ) {
00159   std::stringstream ss(base64_decode( b64 ));
00160   ss >> v;
00161 }
00162 
00163 
00164 
00165 } }  // namespace mace::rpc
00166 #endif // _SCRYPT_BASE64_HPP