2 // System.Security.Cryptography.ToBase64Transform
5 // Sergey Chaban (serge@wildwestsoftware.com)
10 namespace System.Security.Cryptography {
12 public class ToBase64Transform : ICryptoTransform {
14 private bool m_disposed;
17 /// Default constructor.
19 public ToBase64Transform ()
30 public bool CanTransformMultipleBlocks {
36 public bool CanReuseTransform {
41 /// Returns the input block size for the Base64 encoder.
44 /// The returned value is always 3.
46 public int InputBlockSize {
54 /// Returns the output block size for the Base64 encoder.
57 /// The value returned by this property is always 4.
59 public int OutputBlockSize {
70 void IDisposable.Dispose ()
73 GC.SuppressFinalize (this); // Finalization is now unnecessary
76 protected virtual void Dispose (bool disposing)
79 // dispose unmanaged objects
81 // dispose managed objects
89 public int TransformBlock (byte [] inputBuffer,
95 if (inputCount != this.InputBlockSize)
96 throw new CryptographicException();
98 byte [] lookup = Base64Table.EncodeTable;
100 int b1 = inputBuffer [inputOffset];
101 int b2 = inputBuffer [inputOffset + 1];
102 int b3 = inputBuffer [inputOffset + 2];
104 outputBuffer [outputOffset] = lookup [b1 >> 2];
105 outputBuffer [outputOffset+1] = lookup [((b1 << 4) & 0x30) | (b2 >> 4)];
106 outputBuffer [outputOffset+2] = lookup [((b2 << 2) & 0x3c) | (b3 >> 6)];
107 outputBuffer [outputOffset+3] = lookup [b3 & 0x3f];
109 return this.OutputBlockSize;
115 // LAMESPEC: It's not clear from Beta2 docs what should be
116 // happening here if inputCount > InputBlockSize.
117 // It just "Converts the specified region of the specified
118 // byte array" and that's all.
119 // Beta2 implementation throws some strange (and undocumented)
120 // exception in such case. The exception is thrown by
121 // System.Convert and not the method itself.
122 // Anyhow, this implementation just encodes blocks of any size,
123 // like any usual Base64 encoder.
127 public byte [] TransformFinalBlock (byte [] inputBuffer,
131 int blockLen = this.InputBlockSize;
132 int outLen = this.OutputBlockSize;
133 int fullBlocks = inputCount / blockLen;
134 int tail = inputCount % blockLen;
136 byte [] res = new byte [(inputCount != 0)
137 ? ((inputCount + 2) / blockLen) * outLen
140 int outputOffset = 0;
142 for (int i = 0; i < fullBlocks; i++) {
144 TransformBlock (inputBuffer, inputOffset,
145 blockLen, res, outputOffset);
147 inputOffset += blockLen;
148 outputOffset += outLen;
152 byte [] lookup = Base64Table.EncodeTable;
156 // When fewer than 24 input bits are available
157 // in an input group, zero bits are added
158 // (on the right) to form an integral number of
164 b1 = inputBuffer [inputOffset];
165 res [outputOffset] = lookup [b1 >> 2];
166 res [outputOffset+1] = lookup [(b1 << 4) & 0x30];
169 res [outputOffset+2] = (byte)'=';
170 res [outputOffset+3] = (byte)'=';
174 b1 = inputBuffer [inputOffset];
175 b2 = inputBuffer [inputOffset + 1];
176 res [outputOffset] = lookup [b1 >> 2];
177 res [outputOffset+1] = lookup [((b1 << 4) & 0x30) | (b2 >> 4)];
178 res [outputOffset+2] = lookup [(b2 << 2) & 0x3c];
181 res [outputOffset+3] = (byte)'=';
191 } // ToBase64Transform
196 [MonoTODO ("Put me in a separate file")]
197 internal sealed class Base64Table {
199 // This is the Base64 alphabet as described in RFC 2045
200 // (Table 1, page 25).
201 private static string ALPHABET =
202 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
204 private static byte[] encodeTable;
205 private static byte[] decodeTable;
208 static Base64Table ()
210 int len = ALPHABET.Length;
212 encodeTable = new byte [len];
214 for (int i=0; i < len; i++) {
215 encodeTable [i] = (byte) ALPHABET [i];
219 decodeTable = new byte [1 + (int)'z'];
221 for (int i=0; i < decodeTable.Length; i++) {
222 decodeTable [i] = Byte.MaxValue;
225 for (int i=0; i < len; i++) {
226 char ch = ALPHABET [i];
227 decodeTable [(int)ch] = (byte) i;
232 private Base64Table ()
234 // Never instantiated.
238 internal static byte [] EncodeTable {
244 internal static byte [] DecodeTable {
252 } // System.Security.Cryptography