1 // Base64.cpp: implementation of the CBase64 class.
3 //////////////////////////////////////////////////////////////////////
10 static char THIS_FILE
[]=__FILE__
;
14 //////////////////////////////////////////////////////////////////////
16 //////////////////////////////////////////////////////////////////////
17 // Static Member Initializers
20 // The 7-bit alphabet used to encode binary information
21 const char m_sBase64Alphabet
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
23 const int f_nMask
[] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
37 CStringA
CBase64::Encode( IN
const char* szEncoding
, IN
int nSize
)
39 CStringA sOutput
= "";
45 ASSERT( szEncoding
!= NULL
);
46 if( szEncoding
== NULL
)
48 m_szInput
= szEncoding
;
52 nDigit
= read_bits( nNumBits
, &nNumBits
, lp
);
55 sOutput
+= m_sBase64Alphabet
[ (int)nDigit
];
56 nDigit
= read_bits( nNumBits
, &nNumBits
, lp
);
62 // Pad with '=' as per RFC 1521
63 while( sOutput
.GetLength() % 4 != 0 )
70 // The size of the output buffer must not be less than
71 // 3/4 the size of the input buffer. For simplicity,
72 // make them the same size.
73 // return : ½âÂëºóÊý¾Ý³¤¶È
74 int CBase64::Decode ( IN
const char* szDecoding
, char* szOutput
)
81 ASSERT( szDecoding
!= NULL
);
82 ASSERT( szOutput
!= NULL
);
83 if( szOutput
== NULL
)
85 if( szDecoding
== NULL
)
88 if( sInput
.GetLength() == 0 )
94 for( i
= 0; i
< 256; i
++ )
95 nDecode
[i
] = -2; // Illegal digit
96 for( i
=0; i
< 64; i
++ )
98 nDecode
[ m_sBase64Alphabet
[ i
] ] = i
;
99 nDecode
[ m_sBase64Alphabet
[ i
] | 0x80 ] = i
; // Ignore 8th bit
100 nDecode
[ '\r' ] = -1;
101 nDecode
[ '\n' ] = -1;
103 nDecode
[ '=' | 0x80 ] = -1; // Ignore MIME padding char
106 // Clear the output buffer
107 memset( szOutput
, 0, sInput
.GetLength() + 1 );
111 for( lp
= 0, i
= 0; lp
< sInput
.GetLength(); lp
++ )
114 nDigit
= nDecode
[ c
& 0x7F ];
119 else if( nDigit
>= 0 )
120 // i (index into output) is incremented by write_bits()
121 write_bits( nDigit
& 0x3F, 6, szOutput
, i
);
126 UINT
CBase64::read_bits(int nNumBits
, int * pBitsRead
, int& lp
)
129 while( ( m_nBitsRemaining
< nNumBits
) &&
130 ( lp
< m_nInputSize
) )
132 int c
= m_szInput
[ lp
++ ];
134 m_lBitStorage
|= (c
& 0xff);
135 m_nBitsRemaining
+= 8;
137 if( m_nBitsRemaining
< nNumBits
)
139 lScratch
= m_lBitStorage
<< ( nNumBits
- m_nBitsRemaining
);
140 *pBitsRead
= m_nBitsRemaining
;
141 m_nBitsRemaining
= 0;
145 lScratch
= m_lBitStorage
>> ( m_nBitsRemaining
- nNumBits
);
146 *pBitsRead
= nNumBits
;
147 m_nBitsRemaining
-= nNumBits
;
149 return (UINT
)lScratch
& f_nMask
[nNumBits
];
153 void CBase64::write_bits(UINT nBits
,
160 m_lBitStorage
= (m_lBitStorage
<< nNumBits
) | nBits
;
161 m_nBitsRemaining
+= nNumBits
;
162 while( m_nBitsRemaining
> 7 )
164 nScratch
= m_lBitStorage
>> (m_nBitsRemaining
- 8);
165 szOutput
[ i
++ ] = nScratch
& 0xFF;
166 m_nBitsRemaining
-= 8;