| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- //
- // System.Security.Cryptography.ToBase64Transform
- //
- // Author:
- // Sergey Chaban ([email protected])
- //
- using System;
- using System.Security.Cryptography;
- namespace System.Security.Cryptography {
- public class ToBase64Transform : ICryptoTransform {
- /// <summary>
- /// Default constructor.
- /// </summary>
- public ToBase64Transform ()
- {
- }
- /// <summary>
- /// </summary>
- public virtual bool CanTransformMultipleBlocks {
- get {
- return false;
- }
- }
- /// <summary>
- /// Returns the input block size for the Base64 encoder.
- /// </summary>
- /// <remarks>
- /// The returned value is always 3.
- /// </remarks>
- public virtual int InputBlockSize {
- get {
- return 3;
- }
- }
- /// <summary>
- /// Returns the output block size for the Base64 encoder.
- /// </summary>
- /// <remarks>
- /// The value returned by this property is always 4.
- /// </remarks>
- public virtual int OutputBlockSize {
- get {
- return 4;
- }
- }
- /// <summary>
- /// </summary>
- public virtual int TransformBlock (byte [] inputBuffer,
- int inputOffset,
- int inputCount,
- byte [] outputBuffer,
- int outputOffset)
- {
- if (inputCount != this.InputBlockSize)
- throw new CryptographicException();
- byte [] lookup = Base64Table.EncodeTable;
- int b1 = inputBuffer [inputOffset];
- int b2 = inputBuffer [inputOffset + 1];
- int b3 = inputBuffer [inputOffset + 2];
- outputBuffer [outputOffset] = lookup [b1 >> 2];
- outputBuffer [outputOffset+1] = lookup [((b1 << 4) & 0x30) | (b2 >> 4)];
- outputBuffer [outputOffset+2] = lookup [((b2 << 2) & 0x3c) | (b3 >> 6)];
- outputBuffer [outputOffset+3] = lookup [b3 & 0x3f];
- return this.OutputBlockSize;
- }
- // LAMESPEC: It's not clear from Beta2 docs what should be
- // happening here if inputCount > InputBlockSize.
- // It just "Converts the specified region of the specified
- // byte array" and that's all.
- // Beta2 implementation throws some strange (and undocumented)
- // exception in such case. The exception is thrown by
- // System.Convert and not the method itself.
- // Anyhow, this implementation just encodes blocks of any size,
- // like any usual Base64 encoder.
- /// <summary>
- /// </summary>
- public virtual byte [] TransformFinalBlock (byte [] inputBuffer,
- int inputOffset,
- int inputCount)
- {
- int blockLen = this.InputBlockSize;
- int outLen = this.OutputBlockSize;
- int fullBlocks = inputCount / blockLen;
- int tail = inputCount % blockLen;
- byte [] res = new byte [(inputCount != 0)
- ? ((inputCount + 2) / blockLen) * outLen
- : 0];
- int outputOffset = 0;
- for (int i = 0; i < fullBlocks; i++) {
- TransformBlock (inputBuffer, inputOffset,
- blockLen, res, outputOffset);
- inputOffset += blockLen;
- outputOffset += outLen;
- }
- byte [] lookup = Base64Table.EncodeTable;
- int b1,b2;
- // When fewer than 24 input bits are available
- // in an input group, zero bits are added
- // (on the right) to form an integral number of
- // 6-bit groups.
- switch (tail) {
- case 0:
- break;
- case 1:
- b1 = inputBuffer [inputOffset];
- res [outputOffset] = lookup [b1 >> 2];
- res [outputOffset+1] = lookup [(b1 << 4) & 0x30];
- // padding
- res [outputOffset+2] = (byte)'=';
- res [outputOffset+3] = (byte)'=';
- break;
- case 2:
- b1 = inputBuffer [inputOffset];
- b2 = inputBuffer [inputOffset + 1];
- res [outputOffset] = lookup [b1 >> 2];
- res [outputOffset+1] = lookup [((b1 << 4) & 0x30) | (b2 >> 4)];
- res [outputOffset+2] = lookup [(b2 << 2) & 0x3c];
- // one-byte padding
- res [outputOffset+3] = (byte)'=';
- break;
- default:
- break;
- }
- return res;
- }
- /// <summary>
- /// </summary>
- public override string ToString ()
- {
- return "mono::System.Security.Cryptography.ToBase64Transform";
- }
- } // ToBase64Transform
- // FIXME: Ought to be in a standalone file.
- internal sealed class Base64Table {
- // This is the Base64 alphabet as described in RFC 2045
- // (Table 1, page 25).
- private static string ALPHABET =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- private static byte[] encodeTable;
- private static byte[] decodeTable;
- static Base64Table ()
- {
- int len = ALPHABET.Length;
- encodeTable = new byte [len];
- for (int i=0; i < len; i++) {
- encodeTable [i] = (byte) ALPHABET [i];
- }
- decodeTable = new byte [1 + (int)'z'];
- for (int i=0; i < decodeTable.Length; i++) {
- decodeTable [i] = Byte.MaxValue;
- }
- for (int i=0; i < len; i++) {
- char ch = ALPHABET [i];
- decodeTable [(int)ch] = (byte) i;
- }
- }
- private Base64Table ()
- {
- // Never instantiated.
- }
- internal static byte [] EncodeTable {
- get {
- return encodeTable;
- }
- }
- internal static byte [] DecodeTable {
- get {
- return decodeTable;
- }
- }
- } // Base64Table
- } // System.Security.Cryptography
|