Additional Code - 6 KB

Listing 1: A Custom Base64 Encoder

public class MyConverter
{
  public static string ToBase64String(byte[] value)
  {
    // Base64 chars
    char[] base64Chars = 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','+','/' };

    int numBlocks;
    int padBytes;

    if ((value.Length % 3) == 0)
    {
      numBlocks = value.Length / 3;
      padBytes = 0;
    }
    else
    {
      numBlocks = 1 + (value.Length / 3);
      padBytes = 3 - (value.Length % 3);
    }
    if (padBytes < 0 || padBytes > 3)
      throw new Exception("Fatal logic error in padding code");

    // create a lengthened and padded input byte array
    byte[] newValue = new byte[numBlocks * 3];
    for (int i = 0; i < newValue.Length; ++i) // not really necesary
      newValue[i] = 0;
    for (int i = 0; i < value.Length; ++i)
        newValue[i] = value[i];

    byte[] resultBytes = new byte[numBlocks * 4];
    char[] resultChars = new char[numBlocks * 4];

    for (int i = 0; i < numBlocks; i++)
    {
      resultBytes[i * 4 + 0] =
       (byte)((newValue[i * 3 + 0] & 0xFC) >> 2);
      resultBytes[i * 4 + 1] =
       (byte)((newValue[i * 3 + 0] & 0x03) << 4 |
              (newValue[i * 3 + 1] & 0xF0) >> 4);
      resultBytes[i * 4 + 2] =
       (byte)((newValue[i * 3 + 1] & 0x0F) << 2 |
              (newValue[i * 3 + 2] & 0xC0) >> 6);
      resultBytes[i * 4 + 3] =
       (byte)((newValue[i * 3 + 2] & 0x3F));
    }

    for (int i = 0; i < numBlocks * 4; ++i)
      resultChars[i] = base64Chars[resultBytes[i]];

    // pad the resultChars array tail with '=' chars
    if (padBytes == 0)
      ;
    else if (padBytes == 1)
      resultChars[numBlocks * 4 - 1] = '=';
    else if (padBytes == 2)
    {
      resultChars[numBlocks * 4 - 1] = '=';
      resultChars[numBlocks * 4 - 2] = '=';
    }

    string s = new string(resultChars);
    return s;
  } // ToBase64String()

} // class MyConverter


Listing 2: A Custom Base64 Decoder

public static byte[] FromBase64String(string s)
{
  // determine how many trailing '=' signs
  int last = s.IndexOf('=');
  int padCount = 0;

  if (last == -1)
    padCount = 0;
  else if (last == s.Length - 1)
    padCount = 1;
  else if (last == s.Length - 2)
    padCount = 2;

  int numBlocks = s.Length / 4;
  byte[] result = new byte[numBlocks * 3];

  for (int i = 0; i < numBlocks; ++i)
  {
    byte[] scratch = new byte[4];
    scratch[0] = ValueOf(s[i * 4 + 0]);
    scratch[1] = ValueOf(s[i * 4 + 1]);
    scratch[2] = ValueOf(s[i * 4 + 2]); // possibly '='
    scratch[3] = ValueOf(s[i * 4 + 3]); // possibly '='

    result[i * 3 + 0] =
     (byte)((scratch[0] << 0x02) |
            (scratch[1] & 0x30) >> 4) ;
    result[i * 3 + 1] =
     (byte)((scratch[1] & 0x0F) << 4 |
           (scratch[2] & 0x3C) >> 2);
    result[i * 3 + 2] =
     (byte)((scratch[2] & 0x03) << 6 | scratch[3]);

  }

  byte[] finalResult = new byte[result.Length - padCount];
  for (int i = 0; i < finalResult.Length; ++i)
    finalResult[i] = result[i];
  return finalResult;
} // ToByteArray()

private static byte ValueOf(char c) // value for Base64 character
{
  if (c >= 'A' && c <= 'Z')
    return (byte)((int)c - 65);
  else if (c >= 'a' && c <= 'z')
    return (byte)((int)c - 71);
  else if (c >= '0' && c <= '9')
    return (byte)((int)c + 4);
  else if (c == '+')
    return 62;
  else if (c == '/')
    return 63;
  else
    return 0;
}

Listing 3: Base64 Encoding Demo

static void Main(string[] args)
{
  try
  {
    Console.WriteLine("\nStart Base64 encoding demo\n");

    string seed = "Hello";
    Console.WriteLine("  Seed string to generate some bytes is: '" + seed + "'");
    byte[] b = System.Text.Encoding.ASCII.GetBytes(seed);
    Console.WriteLine("  In hexadecimal encoding the bytes are:
	" + BitConverter.ToString(b) + "\n");
    Console.WriteLine("===============\n");

    string s1 = Convert.ToBase64String(b);
    Console.WriteLine("  Using Framework the Base64 encoding is: " + s1 + "\n");
    string s2 = MyConverter.ToBase64String(b);
    Console.WriteLine("  Using custom method Base64 encoding is: " + s2 + "\n");
    Console.WriteLine("===============\n");

    byte[] b1 = Convert.FromBase64String(s1);
    string h1  = BitConverter.ToString(b1);
    Console.WriteLine("  Using Framework the original bytes are: " + h1 + "\n");

    byte[] b2 = MyConverter.FromBase64String(s2);
    string h2 = BitConverter.ToString(b2);
    Console.WriteLine("  Using custom method original bytes are: " + h2 + "\n");

    Console.WriteLine("\nEnd demo");
    Console.ReadLine();
  }
  catch (Exception ex)
  {
    Console.WriteLine("Fatal: " + ex.Message);
    Console.ReadLine();
  }
} // Main()

Additional Code - 6 KB