The Base64 utility class performs base64 encoding and decoding.

image_pdfimage_print
   
 

/******************************************************************************
* 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> Encodes the specified bytes into a base64 array of bytes.
    /// Each byte in the return array represents a base64 character.
    /// 
    /// </summary>
    /// <param name="inputBytes"> the byte array to be encoded.
    /// 
    /// </param>
    /// <returns>            a String containing the base64 encoded data
    /// </returns>
    [CLSCompliantAttribute(false)]
    public static System.String encode(sbyte[] inputBytes)
    {
        /// <summary>Conversion table for encoding to base64.
        /// 
        /// emap is a six-bit value to base64 (8-bit) converstion table.
        /// For example, the value of the 6-bit value 15
        /// is mapped to 0x50 which is the ASCII letter &#039;P&#039;, i.e. the letter P
        /// is the base64 encoded character that represents the 6-bit value 15.
        /// </summary>
        /*
        * 8-bit base64 encoded character                 base64       6-bit
        *                                                encoded      original
        *                                                character    binary value
        */
        char[] emap = new char[]{&#039;A&#039;, &#039;B&#039;, &#039;C&#039;, &#039;D&#039;, &#039;E&#039;, &#039;F&#039;, &#039;G&#039;, &#039;H&#039;, &#039;I&#039;, &#039;J&#039;, &#039;K&#039;, &#039;L&#039;, &#039;M&#039;, &#039;N&#039;, &#039;O&#039;, &#039;P&#039;, &#039;Q&#039;, &#039;R&#039;, &#039;S&#039;, &#039;T&#039;, &#039;U&#039;, &#039;V&#039;, &#039;W&#039;, &#039;X&#039;, &#039;Y&#039;, &#039;Z&#039;, &#039;a&#039;, &#039;b&#039;, &#039;c&#039;, &#039;d&#039;, &#039;e&#039;, &#039;f&#039;, &#039;g&#039;, &#039;h&#039;, &#039;i&#039;, &#039;j&#039;, &#039;k&#039;, &#039;l&#039;, &#039;m&#039;, &#039;n&#039;, &#039;o&#039;, &#039;p&#039;, &#039;q&#039;, &#039;r&#039;, &#039;s&#039;, &#039;t&#039;, &#039;u&#039;, &#039;v&#039;, &#039;w&#039;, &#039;x&#039;, &#039;y&#039;, &#039;z&#039;, &#039;0&#039;, &#039;1&#039;, &#039;2&#039;, &#039;3&#039;, &#039;4&#039;, &#039;5&#039;, &#039;6&#039;, &#039;7&#039;, &#039;8&#039;, &#039;9&#039;, &#039;+&#039;, &#039;/&#039;}; // 4-9, + /;  56-63
        


      int i, j, k;
      int t, t1, t2;
      int ntb; // number of three-bytes in inputBytes
      bool onePadding = false, twoPaddings = false;
      char[] encodedChars; // base64 encoded chars
      int len = inputBytes.Length;
      
      if (len == 0)
      {
        // No data, return no data.
        return new System.Text.StringBuilder("").ToString();
      }
      
      // every three bytes will be encoded into four bytes
      if (len % 3 == 0)
      {
        ntb = len / 3;
      }
      // the last one or two bytes will be encoded into
      // four bytes with one or two paddings
      else
      {
        ntb = len / 3 + 1;
      }
      
      // need two paddings
      if ((len % 3) == 1)
      {
        twoPaddings = true;
      }
      // need one padding
      else if ((len % 3) == 2)
      {
        onePadding = true;
      }
      
      encodedChars = new char[ntb * 4];
      
      // map of decoded and encoded bits
      //     bits in 3 decoded bytes:   765432  107654  321076  543210
      //     bits in 4 encoded bytes: 76543210765432107654321076543210
      //       plain           "AAA":   010000  010100  000101  000001
      //       base64 encoded "QUFB": 00010000000101000000010100000001
      // one padding:
      //     bits in 2 decoded bytes:   765432  10 7654  3210
      //     bits in 4 encoded bytes: 765432107654 321076543210 &#039;=&#039;
      //       plain            "AA":   010000  010100  0001
      //       base64 encoded "QUE=": 00010000000101000000010000111101
      // two paddings:
      //     bits in 1 decoded bytes:   765432  10
      //     bits in 4 encoded bytes: 7654321076543210 &#039;=&#039; &#039;=&#039;
      //       plain             "A":   010000  01
      //       base64 encoded "QQ==": 00010000000100000011110100111101
      //
      // note: the encoded bits which have no corresponding decoded bits
      // are filled with zeros; &#039;=&#039; = 00111101.
      for (i = 0, j = 0, k = 1; i < len; i += 3, j += 4, k++)
      {
        
        // build encodedChars&#91;j&#93;
        t = 0x00ff &amp; inputBytes&#91;i&#93;;
        encodedChars&#91;j&#93; = emap&#91;t >> 2];
        
        // build encodedChars[j+1]
        if ((k == ntb) &amp;&amp; twoPaddings)
        {
          encodedChars[j + 1] = emap[(t &amp; 0x03) << 4&#93;;
          encodedChars&#91;j + 2&#93; = &#039;=&#039;;
          encodedChars&#91;j + 3&#93; = &#039;=&#039;;
          break;
        }
        else
        {
          t1 = 0x00ff &amp; inputBytes&#91;i + 1&#93;;
          encodedChars&#91;j + 1&#93; = emap&#91;((t &amp; 0x03) << 4) + ((t1 &amp; 0xf0) >> 4)];
        }
        
        // build encodedChars[j+2]
        if ((k == ntb) &amp;&amp; onePadding)
        {
          encodedChars[j + 2] = emap[(t1 &amp; 0x0f) << 2&#93;;
          encodedChars&#91;j + 3&#93; = &#039;=&#039;;
          break;
        }
        else
        {
          t2 = 0x00ff &amp; inputBytes&#91;i + 2&#93;;
          encodedChars&#91;j + 2&#93; = (emap&#91;(t1 &amp; 0x0f) << 2 | (t2 &amp; 0xc0) >> 6]);
        }
        
        // build encodedChars[j+3]
        encodedChars[j + 3] = (emap[(t2 &amp; 0x3f)]);
      }
      return new System.String(encodedChars);
    }
   }
}