C++ Base64 Class

/* ***********************************************
 *                                                *
 * CBase64.h                                    *
 * Base 64 de- and encoding class                *
 *                                                *
 * ============================================ *
 *                                                *
 * This class was written on 28.05.2003            *
 * by Jan Raddatz [jan-raddatz@web.de]            *
 *                                                *
 * ============================================ *
 *                                                *
 * Copyright (c) by Jan Raddatz                    *
 * This class was published @ codeguru.com        *
 * 28.05.2003                                    *
 *                                                *
 ***********************************************
*/

#pragma once

#include 
< afx.h >
#include 
< stdlib.h >
#include 
< math.h >
#include 
< memory.h >
const   static  unsigned  int  MAX_LINE_LENGTH  =   76 ;

const   static   char  BASE64_ALPHABET [ 64 =  
    {
    
' A ' ' B ' ' C ' ' D ' ' E ' ' F ' ' G ' ' H ' ' I ' ' J ' //    0 -   9
     ' K ' ' L ' ' M ' ' N ' ' O ' ' P ' ' Q ' ' R ' ' S ' ' T ' //   10 -  19
     ' U ' ' V ' ' W ' ' X ' ' Y ' ' Z ' ' a ' ' b ' ' c ' ' d ' //   20 -  29
     ' e ' ' f ' ' g ' ' h ' ' i ' ' j ' ' k ' ' l ' ' m ' ' n ' //   30 -  39
     ' o ' ' p ' ' q ' ' r ' ' s ' ' t ' ' u ' ' v ' ' w ' ' x ' //   40 -  49
     ' y ' ' z ' ' 0 ' ' 1 ' ' 2 ' ' 3 ' ' 4 ' ' 5 ' ' 6 ' ' 7 ' //   50 -  59
     ' 8 ' ' 9 ' ' + ' ' / '                                    //   60 -  63
    };

const   static   char  BASE64_DEALPHABET [ 128 =  
    {
     
0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 //    0 -   9
      0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 //   10 -  19
      0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 //   20 -  29
      0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 //   30 -  39
      0 ,   0 ,   0 62 ,   0 ,   0 ,   0 63 52 53 //   40 -  49
     54 55 56 57 58 59 60 61 ,   0 ,   0 //   50 -  59
      0 61 ,   0 ,   0 ,   0 ,   0 ,   1 ,   2 ,   3 ,   4 //   60 -  69
      5 ,   6 ,   7 ,   8 ,   9 10 11 12 13 14 //   70 -  79
     15 16 17 18 19 20 21 22 23 24 //   80 -  89
     25 ,   0 ,   0 ,   0 ,   0 ,   0 ,   0 26 27 28 //   90 -  99
     29 30 31 32 33 34 35 36 37 38 //  100 - 109
     39 40 41 42 43 44 45 46 47 48 //  110 - 119
     49 50 51 ,   0 ,   0 ,   0 ,   0 ,   0              //  120 - 127
    };

enum
    {
    UNABLE_TO_OPEN_INPUT_FILE,
    UNABLE_TO_OPEN_OUTPUT_FILE,
    UNABLE_TO_CREATE_OUTPUTBUFFER
    };

class  CBase64
    {
    
public :
        CBase64 ();

        unsigned 
int  CalculateRecquiredEncodeOutputBufferSize (unsigned  int  p_InputByteCount);
        unsigned 
int  CalculateRecquiredDecodeOutputBufferSize ( char *  p_pInputBufferString);

        
void             EncodeByteTriple  ( char *  p_pInputBuffer, unsigned  int  InputCharacters,  char *  p_pOutputBuffer);
        unsigned 
int     DecodeByteQuartet ( char *  p_pInputBuffer,  char *  p_pOutputBuffer);

        
void             EncodeBuffer ( char *  p_pInputBuffer, unsigned  int  p_InputBufferLength,  char * p_pOutputBufferString);
        unsigned 
int     DecodeBuffer ( char *  p_pInputBufferString,  char *  p_pOutputBuffer);

        unsigned 
int  CreateMatchingEncodingBuffer (unsigned  int  p_InputByteCount,  char **  p_ppEncodingBuffer);
        unsigned 
int  CreateMatchingDecodingBuffer ( char *  p_pInputBufferString,  char **  p_ppDecodingBuffer);

        unsigned 
int  EncodeFile ( char *  p_pSourceFileName,  char *  p_pEncodedFileName);
        unsigned 
int  DecodeFile ( char *  p_pSourceFileName,  char *  p_pDecodedFileName);
    };

/* ***********************************************
 *                                                *
 * CBase64.cpp                                    *
 * Base 64 de- and encoding class                *
 *                                                *
 * ============================================ *
 *                                                *
 * This class was written on 28.05.2003            *
 * by Jan Raddatz [jan-raddatz@web.de]            *
 *                                                *
 * ============================================ *
 *                                                *
 * Copyright (c) by Jan Raddatz                    *
 * This class was published @ codeguru.com        *
 * 28.05.2003                                    *
 *                                                *
 ***********************************************
*/

#include 
" CBase64.h "


CBase64::CBase64 ()
    {
    }

unsigned 
int  CBase64::CalculateRecquiredEncodeOutputBufferSize (unsigned  int  p_InputByteCount)
    {
    div_t result 
=  div (p_InputByteCount,  3 );

    unsigned 
int  RecquiredBytes  =   0 ;
    
if  (result.rem  ==   0 )
        {
        
//  Number of encoded characters
        RecquiredBytes  =  result.quot  *   4 ;

        
//  CRLF -> "\r\n" each 76 characters
        result  =  div (RecquiredBytes,  76 );
        RecquiredBytes 
+=  result.quot  *   2 ;

        
//  Terminating null for the Encoded String
        RecquiredBytes  +=   1 ;

        
return  RecquiredBytes;
        }
    
else
        {
        
//  Number of encoded characters
        RecquiredBytes  =  result.quot  *   4   +   4 ;

        
//  CRLF -> "\r\n" each 76 characters
        result  =  div (RecquiredBytes,  76 );
        RecquiredBytes 
+=  result.quot  *   2 ;

        
//  Terminating null for the Encoded String
        RecquiredBytes  +=   1 ;

        
return  RecquiredBytes;
        }
    }

unsigned 
int  CBase64::CalculateRecquiredDecodeOutputBufferSize ( char *  p_pInputBufferString)
    {
    unsigned 
int  BufferLength  =  strlen (p_pInputBufferString);

    div_t result 
=  div (BufferLength,  4 );

    
if  (p_pInputBufferString [BufferLength  -   1 !=   ' = ' )
        {
        
return  result.quot  *   3 ;
        }
    
else
        {
        
if  (p_pInputBufferString [BufferLength  -   2 ==   ' = ' )
            {
            
return  result.quot  *   3   -   2 ;
            }
        
else
            {
            
return  result.quot  *   3   -   1 ;
            }
        }
    }

void  CBase64::EncodeByteTriple  ( char *  p_pInputBuffer, unsigned  int  InputCharacters,  char *  p_pOutputBuffer)
    {
    unsigned 
int  mask  =   0xfc000000 ;
    unsigned 
int  buffer  =   0 ;


    
char *  temp  =  ( char * & buffer;
    temp [
3 =  p_pInputBuffer [ 0 ];
    
if  (InputCharacters  >   1 )
        temp [
2 =  p_pInputBuffer [ 1 ];
    
if  (InputCharacters  >   2 )
        temp [
1 =  p_pInputBuffer [ 2 ];

    
switch  (InputCharacters)
        {
        
case   3 :
            {
            p_pOutputBuffer [
0 =  BASE64_ALPHABET [(buffer  &  mask)  >>   26 ];
            buffer 
=  buffer  <<   6 ;
            p_pOutputBuffer [
1 =  BASE64_ALPHABET [(buffer  &  mask)  >>   26 ];
            buffer 
=  buffer  <<   6 ;
            p_pOutputBuffer [
2 =  BASE64_ALPHABET [(buffer  &  mask)  >>   26 ];
            buffer 
=  buffer  <<   6 ;
            p_pOutputBuffer [
3 =  BASE64_ALPHABET [(buffer  &  mask)  >>   26 ];
            
break ;
            }
        
case   2 :
            {
            p_pOutputBuffer [
0 =  BASE64_ALPHABET [(buffer  &  mask)  >>   26 ];
            buffer 
=  buffer  <<   6 ;
            p_pOutputBuffer [
1 =  BASE64_ALPHABET [(buffer  &  mask)  >>   26 ];
            buffer 
=  buffer  <<   6 ;
            p_pOutputBuffer [
2 =  BASE64_ALPHABET [(buffer  &  mask)  >>   26 ];
            p_pOutputBuffer [
3 =   ' = ' ;
            
break ;
            }
        
case   1 :
            {
            p_pOutputBuffer [
0 =  BASE64_ALPHABET [(buffer  &  mask)  >>   26 ];
            buffer 
=  buffer  <<   6 ;
            p_pOutputBuffer [
1 =  BASE64_ALPHABET [(buffer  &  mask)  >>   26 ];
            p_pOutputBuffer [
2 =   ' = ' ;
            p_pOutputBuffer [
3 =   ' = ' ;
            
break ;
            }
        }
    }

unsigned 
int  CBase64::DecodeByteQuartet ( char *  p_pInputBuffer,  char *  p_pOutputBuffer)
    {
    unsigned 
int  buffer  =   0 ;

    
if  (p_pInputBuffer[ 3 ==   ' = ' )
        {
        
if  (p_pInputBuffer[ 2 ==   ' = ' )
            {
            buffer 
=  (buffer  |  BASE64_DEALPHABET [p_pInputBuffer[ 0 ]])  <<   6 ;
            buffer 
=  (buffer  |  BASE64_DEALPHABET [p_pInputBuffer[ 1 ]])  <<   6 ;
            buffer 
=  buffer  <<   14 ;

            
char *  temp  =  ( char * & buffer;
            p_pOutputBuffer [
0 =  temp [ 3 ];
            
            
return   1 ;
            }
        
else
            {
            buffer 
=  (buffer  |  BASE64_DEALPHABET [p_pInputBuffer[ 0 ]])  <<   6 ;
            buffer 
=  (buffer  |  BASE64_DEALPHABET [p_pInputBuffer[ 1 ]])  <<   6 ;
            buffer 
=  (buffer  |  BASE64_DEALPHABET [p_pInputBuffer[ 2 ]])  <<   6 ;
            buffer 
=  buffer  <<   8 ;

            
char *  temp  =  ( char * & buffer;
            p_pOutputBuffer [
0 =  temp [ 3 ];
            p_pOutputBuffer [
1 =  temp [ 2 ];
            
            
return   2 ;
            }
        }
    
else
        {
        buffer 
=  (buffer  |  BASE64_DEALPHABET [p_pInputBuffer[ 0 ]])  <<   6 ;
        buffer 
=  (buffer  |  BASE64_DEALPHABET [p_pInputBuffer[ 1 ]])  <<   6 ;
        buffer 
=  (buffer  |  BASE64_DEALPHABET [p_pInputBuffer[ 2 ]])  <<   6 ;
        buffer 
=  (buffer  |  BASE64_DEALPHABET [p_pInputBuffer[ 3 ]])  <<   6
        buffer 
=  buffer  <<   2 ;

        
char *  temp  =  ( char * & buffer;
        p_pOutputBuffer [
0 =  temp [ 3 ];
        p_pOutputBuffer [
1 =  temp [ 2 ];
        p_pOutputBuffer [
2 =  temp [ 1 ];

        
return   3 ;
        }

    
return   - 1 ;
    }

void  CBase64::EncodeBuffer ( char *  p_pInputBuffer, unsigned  int  p_InputBufferLength,  char *  p_pOutputBufferString)
    {
    unsigned 
int  FinishedByteQuartetsPerLine  =   0 ;
    unsigned 
int  InputBufferIndex   =   0 ;
    unsigned 
int  OutputBufferIndex  =   0 ;

    memset (p_pOutputBufferString, 
0 , CalculateRecquiredEncodeOutputBufferSize (p_InputBufferLength));

    
while  (InputBufferIndex  <  p_InputBufferLength)
        {
        
if  (p_InputBufferLength  -  InputBufferIndex  <=   2 )
            {
            FinishedByteQuartetsPerLine 
++ ;
            EncodeByteTriple (p_pInputBuffer 
+  InputBufferIndex, p_InputBufferLength  -  InputBufferIndex, p_pOutputBufferString  +  OutputBufferIndex);
            
break ;
            }
        
else
            {
            FinishedByteQuartetsPerLine
++ ;
            EncodeByteTriple (p_pInputBuffer 
+  InputBufferIndex,  3 , p_pOutputBufferString  +  OutputBufferIndex);
            InputBufferIndex  
+=   3 ;
            OutputBufferIndex 
+=   4 ;
            }

        
if  (FinishedByteQuartetsPerLine  ==   19 )
            {
            p_pOutputBufferString [OutputBufferIndex  ] 
=   ' \r ' ;
            p_pOutputBufferString [OutputBufferIndex
+ 1 =   ' \n ' ;
            p_pOutputBufferString 
+=   2 ;
            FinishedByteQuartetsPerLine 
=   0 ;
            }
        }
    }

unsigned 
int  CBase64::DecodeBuffer ( char *  p_pInputBufferString,  char *  p_pOutputBuffer)
    {
    unsigned 
int  InputBufferIndex   =   0 ;
    unsigned 
int  OutputBufferIndex  =   0 ;
    unsigned 
int  InputBufferLength  =  strlen (p_pInputBufferString);

    
char  ByteQuartet [ 4 ];

    
while  (InputBufferIndex  <  InputBufferLength)
        {
        
for  ( int  i  =   0 ; i  <   4 ; i ++ )
            {
            ByteQuartet [i] 
=  p_pInputBufferString [InputBufferIndex];

            
//  Ignore all characters except the ones in BASE64_ALPHABET
             if  ((ByteQuartet [i]  >=   48   &&  ByteQuartet [i]  <=    57 ||
                (ByteQuartet [i] 
>=   65   &&  ByteQuartet [i]  <=    90 ||
                (ByteQuartet [i] 
>=   97   &&  ByteQuartet [i]  <=   122 ||
                 ByteQuartet [i] 
==   ' + '   ||  ByteQuartet [i]  ==   ' / '   ||  ByteQuartet [i]  ==   ' = ' )
                {
                }
            
else
                {
                
//  Invalid character
                i -- ;
                }

            InputBufferIndex
++ ;
            }

        OutputBufferIndex 
+=  DecodeByteQuartet (ByteQuartet, p_pOutputBuffer  +  OutputBufferIndex);
        }

    
//  OutputBufferIndex gives us the next position of the next decoded character
    
//  inside our output buffer and thus represents the number of decoded characters
    
//  in our buffer.
     return  OutputBufferIndex;
    }

unsigned 
int  CBase64::CreateMatchingEncodingBuffer (unsigned  int  p_InputByteCount,  char **  p_ppEncodingBuffer)
    {
    unsigned 
int  Size  =  CalculateRecquiredEncodeOutputBufferSize (p_InputByteCount);
    (
* p_ppEncodingBuffer)  =  ( char * ) malloc (Size);
    memset (
* p_ppEncodingBuffer,  0 , Size);
    
return  Size;
    }

unsigned 
int  CBase64::CreateMatchingDecodingBuffer ( char *  p_pInputBufferString,  char **  p_ppDecodingBuffer)
    {
    unsigned 
int  Size  =  CalculateRecquiredDecodeOutputBufferSize (p_pInputBufferString);
    (
* p_ppDecodingBuffer)  =  ( char * ) malloc (Size);
    memset (
* p_ppDecodingBuffer,  0 , Size);
    
return  Size;
    }

unsigned 
int  CBase64::EncodeFile ( char *  p_pSourceFileName,  char *  p_pEncodedFileName)
    {
    CFile InputFile;
    CFile OutputFile;

    
if  ( ! InputFile.Open (p_pSourceFileName, CFile::modeRead))
        
return  UNABLE_TO_OPEN_INPUT_FILE;

    
if  ( ! OutputFile.Open (p_pEncodedFileName, CFile::modeCreate | CFile::modeWrite))
        
return  UNABLE_TO_OPEN_OUTPUT_FILE;

    
char  InputBuffer [ 19   *   3 ];
    
char *  pOutputBuffer;
    CreateMatchingEncodingBuffer (
sizeof  (InputBuffer),  & pOutputBuffer);

    
if  (pOutputBuffer  ==   0 )
        
return  UNABLE_TO_CREATE_OUTPUTBUFFER;

    unsigned 
int  ReadBytes  =   0 ;
    
while  ((ReadBytes  =  InputFile.Read (InputBuffer,  sizeof  (InputBuffer)))  !=   0 )
        {
        EncodeBuffer (InputBuffer, ReadBytes, pOutputBuffer);
        OutputFile.Write (pOutputBuffer, strlen (pOutputBuffer));
        }

    OutputFile.Flush ();
    OutputFile.Close ();
    InputFile.Close  ();

    
return   0 ;
    }

unsigned 
int  CBase64::DecodeFile ( char *  p_pSourceFileName,  char *  p_pDecodedFileName)
    {
    CStdioFile    InputFile;
    CFile        OutputFile;

    
if  ( ! InputFile.Open (p_pSourceFileName, CFile::modeRead))
        
return  UNABLE_TO_OPEN_INPUT_FILE;

    
if  ( ! OutputFile.Open (p_pDecodedFileName, CFile::modeCreate | CFile::modeWrite))
        
return  UNABLE_TO_OPEN_OUTPUT_FILE;

    CString InputBuffer;
    
char     OutputBuffer[ 64 ];

    unsigned 
int  ReadBytes  =   0 ;
    
while  ((ReadBytes  =  InputFile.ReadString (InputBuffer))  !=   0 )
        {
        InputBuffer.Remove (
' \r ' );
        InputBuffer.Remove (
' \n ' );
        unsigned 
int  DecodedBytes  =  DecodeBuffer ((LPTSTR) (LPCTSTR) InputBuffer, OutputBuffer);
        OutputFile.Write (
& OutputBuffer [ 0 ], DecodedBytes);
        }


    OutputFile.Flush ();
    OutputFile.Close ();
    InputFile.Close  ();

    
return   0 ;
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值