Mega Code Archive

 
Categories / C# / Development Class
 

The Base64 utility class performs base64 encoding and decoding The resulting binary data is returned as an array of byte

/****************************************************************************** * The MIT License * Copyright (c) 2003 Novell Inc.  www.novell.com *  * Permission is hereby granted, free of charge, to any person obtaining  a copy * of this software and associated documentation files (the Software), to deal * in the Software without restriction, including  without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  * copies of the Software, and to  permit persons to whom the Software is  * furnished to do so, subject to the following conditions: *  * The above copyright notice and this permission notice shall be included in  * all copies or substantial portions of the Software. *  * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. *******************************************************************************/ // // Novell.Directory.Ldap.Utilclass.Base64.cs // // Author: //   Sunil Kumar (Sunilk@novell.com) // // (C) 2003 Novell, Inc (http://www.novell.com) // using System; namespace Novell.Directory.Ldap.Utilclass {      /// <summary> The Base64 utility class performs base64 encoding and decoding.   ///    /// The Base64 Content-Transfer-Encoding is designed to represent   /// arbitrary sequences of octets in a form that need not be humanly   /// readable.  The encoding and decoding algorithms are simple, but the   /// encoded data are consistently only about 33 percent larger than the   /// unencoded data.  The base64 encoding algorithm is defined by   /// RFC 2045.   /// </summary>   public class Base64   {       /// <summary> Decodes the input base64 encoded array of characters.     /// The resulting binary data is returned as an array of bytes.     ///      /// </summary>     /// <param name="encodedChars">The character array containing the base64 encoded data.     ///      /// </param>     /// <returns> A byte array object containing decoded bytes.     /// </returns>     [CLSCompliantAttribute(false)]     public static sbyte[] decode(char[] encodedChars)     {         /// <summary>conversion table for decoding from base64.         ///          /// dmap is a base64 (8-bit) to six-bit value converstion table.         /// For example the ASCII character 'P' has a value of 80.         /// The value in the 80th position of the table is 0x0f or 15.         /// 15 is the original 6-bit value that the letter 'P' represents.         /// </summary>         /*         * 6-bit decoded value                            base64    base64         *                                                encoded   character         *                                                value         *         * Note: about half of the values in the table are only place holders         */         sbyte[] dmap = new sbyte[]{(sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x3e), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x3f), (sbyte) (0x34), (sbyte) (0x35), (sbyte) (0x36), (sbyte) (0x37), (sbyte) (0x38), (sbyte) (0x39), (sbyte) (0x3a), (sbyte) (0x3b), (sbyte) (0x3c), (sbyte) (0x3d), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x01), (sbyte) (0x02), (sbyte) (0x03), (sbyte) (0x04), (sbyte) (0x05), (sbyte) (0x06), (sbyte) (0x07), (sbyte) (0x08), (sbyte) (0x09), (sbyte) (0x0a), (sbyte) (0x0b), (sbyte) (0x0c), (sbyte) (0x0d), (sbyte) (0x0e), (sbyte) (0x0f), (sbyte) (0x10), (sbyte) (0x11), (sbyte) (0x12), (sbyte) (0x13), (sbyte) (0x14), (sbyte) (0x15), (sbyte) (0x16), (sbyte) (0x17), (sbyte) (0x18), (sbyte) (0x19), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x1a), (sbyte) (0x1b), (sbyte) (0x1c), (sbyte) (0x1d), (sbyte) (0x1e), (sbyte) (0x1f), (sbyte) (0x20), (sbyte) (0x21), (sbyte) (0x22), (sbyte) (0x23), (sbyte) (0x24), (sbyte) (0x25), (sbyte) (0x26), (sbyte) (0x27), (sbyte) (0x28), (sbyte) (0x29), (sbyte) (0x2a), (sbyte) (0x2b), (sbyte) (0x2c), (sbyte) (0x2d), (sbyte) (0x2e), (sbyte) (0x2f), (sbyte) (0x30), (sbyte) (0x31), (sbyte) (0x32), (sbyte) (0x33), (sbyte) (0x00), (           sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00), (sbyte) (0x00)}; // 120-127 'xyz     '       int i, j, k;       int ecLen = encodedChars.Length; // length of encodedChars       int gn = ecLen / 4; // number of four-byte groups in encodedChars       int dByteLen; // length of decoded bytes, default is '0'       bool onePad = false, twoPads = false;       sbyte[] decodedBytes; // decoded bytes              if (encodedChars.Length == 0)       {         return new sbyte[0];       }       // the number of encoded bytes should be multiple of 4       if ((ecLen % 4) != 0)       {         throw new System.SystemException("Novell.Directory.Ldap.ldif_dsml." + "Base64Decoder: decode: mal-formatted encode value");       }              // every four-bytes in encodedString, except the last one if it in the       // form of '**==' or '***=' ( can't be '*' or ''), will be       // decoded into three bytes.       if ((encodedChars[ecLen - 1] == (int) '=') && (encodedChars[ecLen - 2] == (int) '='))       {         // the last four bytes of encodedChars is in the form of '**=='         twoPads = true;         // the first two bytes of the last four-bytes of encodedChars will         // be decoded into one byte.         dByteLen = gn * 3 - 2;         decodedBytes = new sbyte[dByteLen];       }       else if (encodedChars[ecLen - 1] == '=')       {         // the last four bytes of encodedChars is in the form of '***='         onePad = true;         // the first two bytes of the last four-bytes of encodedChars will         // be decoded into two bytes.         dByteLen = gn * 3 - 1;         decodedBytes = new sbyte[dByteLen];       }       else       {         // the last four bytes of encodedChars is in the form of '****',         // e.g. no pad.         dByteLen = gn * 3;         decodedBytes = new sbyte[dByteLen];       }              // map of encoded and decoded bits       // no padding:       //     bits in 4 encoded bytes: 76543210 76543210 76543210 76543210       //     bits in 3 decoded bytes:   765432   107654   321076   543210       //        base64  string "QUFB":00010000 00010100 000001010 0000001       //          plain string  "AAA":   010000  010100  000101  000001       // one padding:       //     bits in 4 encoded bytes: 76543210 76543210 76543210 76543210       //     bits in 2 decoded bytes:   765432   107654   3210       //       base64  string "QUE=": 00010000 000101000 0000100 00111101       //         plain string   "AA":   010000  010100  0001       // two paddings:       //     bits in 4 encoded bytes: 76543210 76543210 76543210 76543210       //     bits in 1 decoded bytes:   765432   10       //       base64  string "QQ==": 00010000 00010000 00111101 00111101       //         plain string    "A":   010000  01       for (i = 0, j = 0, k = 1; i < ecLen; i += 4, j += 3, k++)       {         // build decodedBytes[j].         decodedBytes[j] = (sbyte) (dmap[encodedChars[i]] << 2 | (dmap[encodedChars[i + 1]] & 0x30) >> 4);                  // build decodedBytes[j+1]         if ((k == gn) && twoPads)         {           break;         }         else         {           decodedBytes[j + 1] = (sbyte) ((dmap[encodedChars[i + 1]] & 0x0f) << 4 | (dmap[encodedChars[i + 2]] & 0x3c) >> 2);         }                  // build decodedBytes[j+2]         if ((k == gn) && onePad)         {           break;         }         else         {           decodedBytes[j + 2] = (sbyte) ((dmap[encodedChars[i + 2]] & 0x03) << 6 | dmap[encodedChars[i + 3]] & 0x3f);         }       }       return decodedBytes;     }     } }