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

base64.cpp

00001 // base64.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 #include "base64.h"
00005 
00006 NAMESPACE_BEGIN(CryptoPP)
00007 
00008 static const int MAX_LINE_LENGTH = 72;
00009 
00010 static const byte vec[] =
00011                 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00012 static const byte padding = '=';
00013    
00014 Base64Encoder::Base64Encoder(BufferedTransformation *outQueue, bool insertLineBreak)
00015         : insertLineBreak(insertLineBreak), Filter(outQueue)
00016 {
00017         inBufSize=0;
00018         lineLength=0;
00019 }
00020 
00021 void Base64Encoder::LineBreak()
00022 {
00023         if (insertLineBreak)
00024                 AttachedTransformation()->Put('\n');
00025         lineLength=0;
00026 }
00027 
00028 void Base64Encoder::EncodeQuantum()
00029 {
00030         byte out;
00031 
00032         out=(inBuf[0] & 0xFC) >> 2;
00033         AttachedTransformation()->Put(vec[out]);
00034 
00035         out=((inBuf[0] & 0x03) << 4) | (inBuf[1] >> 4);
00036         AttachedTransformation()->Put(vec[out]);
00037 
00038         out=((inBuf[1] & 0x0F) << 2) | (inBuf[2] >> 6);
00039         AttachedTransformation()->Put(inBufSize > 1 ? vec[out] : padding);
00040 
00041         out=inBuf[2] & 0x3F;
00042         AttachedTransformation()->Put(inBufSize > 2 ? vec[out] : padding);
00043 
00044         inBufSize=0;
00045         lineLength+=4;
00046 
00047         if (lineLength>=MAX_LINE_LENGTH)
00048                 LineBreak();
00049 }
00050 
00051 void Base64Encoder::Put(const byte *inString, unsigned int length)
00052 {
00053         while (length--)
00054                 Base64Encoder::Put(*inString++);
00055 }
00056 
00057 void Base64Encoder::MessageEnd(int propagation)
00058 {
00059         if (inBufSize)
00060         {
00061                 for (int i=inBufSize;i<3;i++)
00062                         inBuf[i]=0;
00063                 EncodeQuantum();
00064         }
00065 
00066         if (lineLength) // force a line break unless the current line is empty
00067                 LineBreak();
00068 
00069         Filter::MessageEnd(propagation);
00070 }
00071 
00072 Base64Decoder::Base64Decoder(BufferedTransformation *outQueue)
00073         : Filter(outQueue)
00074 {
00075         inBufSize=0;
00076 }
00077 
00078 void Base64Decoder::DecodeQuantum()
00079 {
00080         byte out;
00081 
00082         out = (inBuf[0] << 2) | (inBuf[1] >> 4);
00083         AttachedTransformation()->Put(out);
00084 
00085         out = (inBuf[1] << 4) | (inBuf[2] >> 2);
00086         if (inBufSize > 2) AttachedTransformation()->Put(out);
00087 
00088         out = (inBuf[2] << 6) | inBuf[3];
00089         if (inBufSize > 3) AttachedTransformation()->Put(out);
00090 
00091         inBufSize=0;
00092 }
00093 
00094 int Base64Decoder::ConvToNumber(byte inByte)
00095 {
00096         if (inByte >= 'A' && inByte <= 'Z')
00097                 return (inByte - 'A');
00098 
00099         if (inByte >= 'a' && inByte <= 'z')
00100                 return (inByte - 'a' + 26);
00101 
00102         if (inByte >= '0' && inByte <= '9')
00103                 return (inByte - '0' + 52);
00104 
00105         if (inByte == '+')
00106                 return (62);
00107 
00108         if (inByte == '/')
00109                 return (63);
00110 
00111         return (-1);
00112 }
00113 
00114 void Base64Decoder::Put(const byte *inString, unsigned int length)
00115 {
00116         while (length--)
00117                 Base64Decoder::Put(*inString++);
00118 }
00119 
00120 void Base64Decoder::MessageEnd(int propagation)
00121 {
00122         if (inBufSize)
00123         {
00124                 for (int i=inBufSize;i<4;i++)
00125                         inBuf[i]=0;
00126                 DecodeQuantum();
00127         }
00128 
00129         Filter::MessageEnd(propagation);
00130 }
00131 
00132 NAMESPACE_END

Generated at Mon Jan 15 01:16:29 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000