/******************************************************************************
* 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
{
/// 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.
///
public class Base64
{
/// Encodes the specified bytes into a base64 array of bytes.
/// Each byte in the return array represents a base64 character.
///
///
/// the byte array to be encoded.
///
///
/// a String containing the base64 encoded data
///
[CLSCompliantAttribute(false)]
public static System.String encode(sbyte[] inputBytes)
{
/// 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 'P', i.e. the letter P
/// is the base64 encoded character that represents the 6-bit value 15.
///
/*
* 8-bit base64 encoded character base64 6-bit
* encoded original
* character binary value
*/
char[] emap = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'}; // 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 '='
// plain "AA": 010000 010100 0001
// base64 encoded "QUE=": 00010000000101000000010000111101
// two paddings:
// bits in 1 decoded bytes: 765432 10
// bits in 4 encoded bytes: 7654321076543210 '=' '='
// plain "A": 010000 01
// base64 encoded "QQ==": 00010000000100000011110100111101
//
// note: the encoded bits which have no corresponding decoded bits
// are filled with zeros; '=' = 00111101.
for (i = 0, j = 0, k = 1; i < len; i += 3, j += 4, k++)
{
// build encodedChars[j]
t = 0x00ff & inputBytes[i];
encodedChars[j] = emap[t >> 2];
// build encodedChars[j+1]
if ((k == ntb) && twoPaddings)
{
encodedChars[j + 1] = emap[(t & 0x03) << 4];
encodedChars[j + 2] = '=';
encodedChars[j + 3] = '=';
break;
}
else
{
t1 = 0x00ff & inputBytes[i + 1];
encodedChars[j + 1] = emap[((t & 0x03) << 4) + ((t1 & 0xf0) >> 4)];
}
// build encodedChars[j+2]
if ((k == ntb) && onePadding)
{
encodedChars[j + 2] = emap[(t1 & 0x0f) << 2];
encodedChars[j + 3] = '=';
break;
}
else
{
t2 = 0x00ff & inputBytes[i + 2];
encodedChars[j + 2] = (emap[(t1 & 0x0f) << 2 | (t2 & 0xc0) >> 6]);
}
// build encodedChars[j+3]
encodedChars[j + 3] = (emap[(t2 & 0x3f)]);
}
return new System.String(encodedChars);
}
}
}