Click here to Skip to main content
Click here to Skip to main content

Base64 Encoder/Decoder in C#

By , 19 Nov 2003
 

Introduction

The code implements the encoding and decoding mechanism of Base64, which is widely used in e-Mail encoding and also .NET Viewstate encoding.

Background

It is written based on RFC 1341, using VS.NET 2003.

Notes

I didn't implement filtering and inserting carriage return and newline etc.

Code Listing

Encoder source

using System;

namespace TestBase64
{
  /// <summary>
  /// Summary description for Base64Encoder.
  /// </summary>
  public class Base64Encoder
  {
    byte[] source;
    int length,length2;
    int blockCount;
    int paddingCount;
    public Base64Encoder(byte[] input)
    {
      source=input;
      length=input.Length;
      if((length % 3)==0)
      {
        paddingCount=0;
        blockCount=length/3;
      }
      else
      {
        paddingCount=3-(length % 3);//need to add padding
        blockCount=(length+paddingCount) / 3;
      }
      length2=length+paddingCount;//or blockCount *3
    }

    public char[] GetEncoded()
    {
      byte[] source2;
      source2=new byte[length2];
      //copy data over insert padding
      for (int x=0; x<length2;x++)
      {
        if (x<length)
        {
          source2[x]=source[x];
        }
        else
        {
          source2[x]=0;
        }
      }
      
      byte b1, b2, b3;
      byte temp, temp1, temp2, temp3, temp4;
      byte[] buffer=new byte[blockCount*4];
      char[] result=new char[blockCount*4];
      for (int x=0;x<blockCount;x++)
      {
        b1=source2[x*3];
        b2=source2[x*3+1];
        b3=source2[x*3+2];

        temp1=(byte)((b1 & 252)>>2);//first

        temp=(byte)((b1 & 3)<<4);
        temp2=(byte)((b2 & 240)>>4);
        temp2+=temp; //second

        temp=(byte)((b2 & 15)<<2);
        temp3=(byte)((b3 & 192)>>6);
        temp3+=temp; //third

        temp4=(byte)(b3 & 63); //fourth

        buffer[x*4]=temp1;
        buffer[x*4+1]=temp2;
        buffer[x*4+2]=temp3;
        buffer[x*4+3]=temp4;

      }

      for (int x=0; x<blockCount*4;x++)
      {
        result[x]=sixbit2char(buffer[x]);
      }

      //covert last "A"s to "=", based on paddingCount
      switch (paddingCount)
      {
        case 0:break;
        case 1:result[blockCount*4-1]='=';break;
        case 2:result[blockCount*4-1]='=';
          result[blockCount*4-2]='=';
          break;
        default:break;
      }
      return result;
    }

    private char sixbit2char(byte b)
    {
      char[] lookupTable=new char[64]
          {  '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','+','/'};

      if((b>=0) &&(b<=63))
      {
        return lookupTable[(int)b];
      }
      else
      {
        //should not happen;
        return ' ';
      }
    }
  }
}

Decoder source

using System;

namespace TestBase64
{
  /// <summary>
  /// Summary description for Base64Decoder.
  /// </summary>
  public class Base64Decoder
  {
    char[] source;
    int length, length2, length3;
    int blockCount;
    int paddingCount;
    public Base64Decoder(char[] input)
    {
      int temp=0;
      source=input;
      length=input.Length;

      //find how many padding are there
      for (int x=0;x<2;x++)
      {
        if(input[length-x-1]=='=')
          temp++;
      }
      paddingCount=temp;
      //calculate the blockCount;
      //assuming all whitespace and carriage returns/newline were removed.
      blockCount=length/4;
      length2=blockCount*3;
    }

    public byte[] GetDecoded()
    {
      byte[] buffer=new byte[length];//first conversion result
      byte[] buffer2=new byte[length2];//decoded array with padding

      for(int x=0;x<length;x++)
      {
        buffer[x]=char2sixbit(source[x]);
      }

      byte b, b1,b2,b3;
      byte temp1, temp2, temp3, temp4;

      for(int x=0;x<blockCount;x++)
      {
        temp1=buffer[x*4];
        temp2=buffer[x*4+1];
        temp3=buffer[x*4+2];
        temp4=buffer[x*4+3];        

        b=(byte)(temp1<<2);
        b1=(byte)((temp2 & 48)>>4);
        b1+=b;

        b=(byte)((temp2 & 15)<<4);
        b2=(byte)((temp3 & 60)>>2);
        b2+=b;

        b=(byte)((temp3 & 3)<<6);
        b3=temp4;
        b3+=b;

        buffer2[x*3]=b1;
        buffer2[x*3+1]=b2;
        buffer2[x*3+2]=b3;
      }
      //remove paddings
      length3=length2-paddingCount;
      byte[] result=new byte[length3];

      for(int x=0;x<length3;x++)
      {
        result[x]=buffer2[x];
      }

      return result;
    }

    private byte char2sixbit(char c)
    {
      char[] lookupTable=new char[64]
          {  

    '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','+','/'};
      if(c=='=')
        return 0;
      else
      {
        for (int x=0;x<64;x++)
        {
          if (lookupTable[x]==c)
            return (byte)x;
        }
        //should not reach here
        return 0;
      }

    }

  }
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

wchvic
Web Developer
Canada Canada
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionGreatmemberskhanvilkar@hpiinc.com22-May-13 10:46 
QuestionYou are a livesaver Thank youmemberdl4gbe16-Oct-12 10:13 
GeneralMy vote of 1memberdaylightdj1-May-12 1:20 
QuestionOptimized version available on GithubmemberRamon Smits13-Jan-12 5:43 
GeneralRe: Optimized version available on Githubmemberashishkum23-Jan-12 20:53 
GeneralMy vote of 5groupPalanikumar3111-Aug-11 23:26 
GeneralGood, but throws System.OutOfMemoryException when processing large datamemberjoujoukinder27-Apr-11 4:15 
GeneralMy vote of 5memberJason Newland8-Apr-11 17:34 
GeneralMy vote of 2memberToli Cuturicu22-Oct-10 8:31 
GeneralRe: My vote of 2memberJason Newland8-Apr-11 17:38 
GeneralVery inefficient encodermemberAndyKernahan29-Jun-07 23:06 
GeneralRe: Very inefficient encodermemberTimmMartin27-Feb-08 3:56 
GeneralC#.NET Window applicaitonmembercrish_fn21-Feb-07 8:41 
Generaldecoding is broken if there are linefeedsmemberno_way20-Feb-07 20:08 
GeneralThanks for the codememberWillStay7-Oct-06 3:18 
GeneralReally useful in mail subject decodingmemberK.V.Raja22-Aug-06 4:07 
JokeReliable than .NET version! Thanksmembermeraydin21-Jun-06 20:31 
GeneralRe: Reliable than .NET version! ThanksmemberSenFo24-Jan-07 10:01 
GeneralVery Useful - especially if you want to implement a base 64 encoder for URLmembermonkeydispenser17-Mar-06 1:44 
GeneralDoes not work with email attachmentsmemberTom W.3-May-04 3:47 
General8Bit decoding/encodingmemberAndre Colbiornsen25-Nov-03 22:40 
GeneralConvert.ToBase64String &amp;&amp; Convert.FromBase64String Will do thissussmsraju20-Nov-03 19:12 
GeneralRe: Convert.ToBase64String && Convert.FromBase64String Will do thismemberwchvic20-Nov-03 21:11 
GeneralRe: Convert.ToBase64String &amp;&amp; Convert.FromBase64String Will do thismemberhspc18-May-04 4:12 
GeneralRe: Convert.ToBase64String && Convert.FromBase64String Will do thismemberSenFo24-Jan-07 8:27 
GeneralUseful. :)memberJon Rista20-Nov-03 18:25 
GeneralRe: Useful. :)memberwchvic20-Nov-03 18:32 
GeneralRe: Useful. :)memberdog_spawn21-Nov-03 5:47 
GeneralRe: Useful. :)memberChristopher Pietschmann, MCSD, MCAD3-Feb-05 4:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130617.1 | Last Updated 20 Nov 2003
Article Copyright 2003 by wchvic
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid