00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "base64.h"
00015
00016 namespace gloox
00017 {
00018
00019 namespace Base64
00020 {
00021
00022 static const std::string alphabet64( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" );
00023 static const char pad = '=';
00024 static const char np = (char)std::string::npos;
00025 static char table64vals[] =
00026 {
00027 62, np, np, np, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, np, np, np, np, np,
00028 np, np, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
00029 18, 19, 20, 21, 22, 23, 24, 25, np, np, np, np, np, np, 26, 27, 28, 29, 30, 31,
00030 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
00031 };
00032
00033 inline char table64( unsigned char c )
00034 {
00035 return ( c < 43 || c > 122 ) ? np : table64vals[c-43];
00036 }
00037
00038 const std::string encode64( const std::string& input )
00039 {
00040 std::string encoded;
00041 char c;
00042 const std::string::size_type length = input.length();
00043
00044 encoded.reserve( length * 2 );
00045
00046 for( std::string::size_type i = 0; i < length; ++i )
00047 {
00048 c = static_cast<char>( ( input[i] >> 2 ) & 0x3f );
00049 encoded += alphabet64[c];
00050
00051 c = static_cast<char>( ( input[i] << 4 ) & 0x3f );
00052 if( ++i < length )
00053 c = static_cast<char>( c | static_cast<char>( ( input[i] >> 4 ) & 0x0f ) );
00054 encoded += alphabet64[c];
00055
00056 if( i < length )
00057 {
00058 c = static_cast<char>( ( input[i] << 2 ) & 0x3c );
00059 if( ++i < length )
00060 c = static_cast<char>( c | static_cast<char>( ( input[i] >> 6 ) & 0x03 ) );
00061 encoded += alphabet64[c];
00062 }
00063 else
00064 {
00065 ++i;
00066 encoded += pad;
00067 }
00068
00069 if( i < length )
00070 {
00071 c = static_cast<char>( input[i] & 0x3f );
00072 encoded += alphabet64[c];
00073 }
00074 else
00075 {
00076 encoded += pad;
00077 }
00078 }
00079
00080 return encoded;
00081 }
00082
00083 const std::string decode64( const std::string& input )
00084 {
00085 char c, d;
00086 const std::string::size_type length = input.length();
00087 std::string decoded;
00088
00089 decoded.reserve( length );
00090
00091 for( std::string::size_type i = 0; i < length; ++i )
00092 {
00093 c = table64(input[i]);
00094 ++i;
00095 d = table64(input[i]);
00096 c = static_cast<char>( ( c << 2 ) | ( ( d >> 4 ) & 0x3 ) );
00097 decoded += c;
00098 if( ++i < length )
00099 {
00100 c = input[i];
00101 if( pad == c )
00102 break;
00103
00104 c = table64(input[i]);
00105 d = static_cast<char>( ( ( d << 4 ) & 0xf0 ) | ( ( c >> 2 ) & 0xf ) );
00106 decoded += d;
00107 }
00108
00109 if( ++i < length )
00110 {
00111 d = input[i];
00112 if( pad == d )
00113 break;
00114
00115 d = table64(input[i]);
00116 c = static_cast<char>( ( ( c << 6 ) & 0xc0 ) | d );
00117 decoded += c;
00118 }
00119 }
00120
00121 return decoded;
00122 }
00123
00124 }
00125
00126 }