Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

base64.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * Functions for encoding and decoding strings in MIME's Base64 notation.
00006  *
00007  * Base 64 is pretty easy.  The input is processed in groups of three bytes.
00008  * These 24 bits are split into 4 groups of 6 bits.  Each group of six bits
00009  * is represented by one character in the base64 alphabet, in the encoded
00010  * output.  The alphabet is as follows:
00011  *      ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
00012  * Where 'A' through '/' represent 000000 through 011111, the 64 different
00013  * combinations.  The '=' (100000) is padding and has no value when decoded.
00014  */
00015 
00016 #include "base64.h"
00017 #include <string.h>
00018 
00019 static char * alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
00020                          "0123456789+/=";
00021 
00022 char * base64_encode( const char * str, int length )
00023 /********************************/
00024 {
00025     int    out_length = ( ( length - 1 ) / 3 + 1 ) * 4;
00026     int    in_length  = ( ( length - 1 ) / 3 + 1 ) * 3;
00027     char * out;
00028     char * in;
00029     int    out_pos = 0;
00030     int    in_pos  = 0;
00031 
00032     out = new char[ out_length + 1 ];
00033     in  = new char[ in_length  + 1 ];
00034     memset( in, '\0', in_length+1 );
00035     memcpy ( in, str, length*sizeof(char));
00036 
00037     for( ;; ) {
00038         if (out_pos < out_length)
00039             (out[ out_pos ] = alphabet[ in[ in_pos ] >> 2]);
00040         else
00041             break;
00042 
00043         if (out_pos+1 < out_length)
00044             (out[ out_pos + 1 ] = alphabet[ ( ( in[ in_pos ] & 0x03 ) << 4 ) | ( in[ in_pos+1 ] >> 4 ) ]);
00045         else
00046             break;
00047 
00048         if (out_pos+2 < out_length)
00049             (out[ out_pos + 2 ] = alphabet[ ( ( in[ in_pos+1 ] & 0x0f ) << 2 ) | ( in[ in_pos+2 ] >> 6 ) ]);
00050         else
00051             break;
00052 
00053         if (out_pos+3 < out_length)
00054             (out[ out_pos + 3 ] = alphabet[ in[ in_pos+2 ] & 0x3f ]);
00055         else
00056             break;
00057 
00058         in_pos += 3;
00059         out_pos += 4;
00060     }
00061 
00062     out[ out_length ] = '\0';
00063     delete in;
00064 
00065     // Now how many '=' signs should we have had at the end?
00066     switch( length % 3 ) {
00067         case 1:
00068             out[ out_length-2 ] = '=';
00069             // FALL THROUGH
00070         case 2:
00071             out[ out_length-1 ] = '=';
00072             break;
00073         case 0:
00074         default:
00075             break;
00076     }
00077 
00078     return( out );
00079 }
00080 
00081 static inline char ofs( char p )
00082 /******************************/
00083 // Takes a base-64 alpha p, and returns its offset in the alphabet, 0-64.
00084 {
00085     return( strchr( alphabet, p ) - alphabet );
00086 }
00087 
00088 char * base64_decode( char * str, int length )
00089 /********************************/
00090 // No error checking is performed!  Assume str really is a Base64 stream!
00091 {
00092     char * out;
00093     int    out_length;
00094     int    out_pos = 0;
00095     int    in_pos  = 0;
00096 
00097     // First found out how long the decoded string will be.
00098     out_length = length / 4 * 3;
00099     if( str[ length - 1 ] == '=' )
00100         out_length--;
00101     if( str[ length - 2 ] == '=' )
00102         out_length--;
00103 
00104     out = new char[ out_length + 1];
00105     for( ;; ) {
00106         if( str[ in_pos ] == '\0' )  break;
00107         out[ out_pos ] = ( ofs( str[ in_pos ] ) << 2 )
00108                        | ( ofs( str[ in_pos+1 ] ) >> 4 );
00109         if( str[ in_pos+2 ] == '=' ) break;
00110         out[ out_pos + 1 ] = ( ( ofs( str[ in_pos+1 ] ) & 0x0f ) << 4 )
00111                              | ( ofs( str[ in_pos+2 ] ) >> 2 );
00112         if( str[ in_pos+3 ] == '=' ) break;
00113         out[ out_pos + 2 ] = ( ( ofs( str[ in_pos+2 ] ) & 0x03 ) << 6 )
00114                                | ofs( str[ in_pos+3 ] );
00115         in_pos  += 4;
00116         out_pos += 3;
00117     }
00118 
00119     out[ out_length ] = '\0';
00120     return( out );
00121 }

Generated on Sun Aug 25 12:41:58 2002 for WvStreams by doxygen1.2.15