5,317,598 members and growing! (26,032 online)
Email Password   helpLost your password?
Languages » C# » General     Intermediate

Base64 Encoder/Decoder in C#

By wchvic

An implementation of Base64 encoding/decoding in C#
C#, Windows, .NET 1.1, .NETVisual Studio, VS.NET2003, Dev

Posted: 19 Nov 2003
Updated: 19 Nov 2003
Views: 107,419
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
31 votes for this Article.
Popularity: 4.73 Rating: 3.17 out of 5
10 votes, 32.3%
1
1 vote, 3.2%
2
1 vote, 3.2%
3
6 votes, 19.4%
4
13 votes, 41.9%
5

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;
      char[] result=new char;
      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='=';break;
        case 2:result='=';
          result='=';
          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



Occupation: Web Developer
Location: Canada Canada

Other popular C# articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 19 of 19 (Total in Forum: 19) (Refresh)FirstPrevNext
Subject  Author Date 
GeneralVery inefficient encodermemberAndyKernahan0:06 30 Jun '07  
GeneralRe: Very inefficient encodermemberTimmMartin4:56 27 Feb '08  
GeneralC#.NET Window applicaitonmembercrish_fn9:41 21 Feb '07  
Generaldecoding is broken if there are linefeedsmemberno_way21:08 20 Feb '07  
GeneralThanks for the codememberWillStay4:18 7 Oct '06  
GeneralReally useful in mail subject decodingmemberK.V.Raja5:07 22 Aug '06  
JokeReliable than .NET version! Thanksmembermeraydin21:31 21 Jun '06  
GeneralRe: Reliable than .NET version! ThanksmemberSenFo11:01 24 Jan '07  
GeneralVery Useful - especially if you want to implement a base 64 encoder for URLmembermonkeydispenser2:44 17 Mar '06  
GeneralDoes not work with email attachmentsmemberTom W.4:47 3 May '04  
General8Bit decoding/encodingmemberAndre Colbiornsen23:40 25 Nov '03  
GeneralConvert.ToBase64String && Convert.FromBase64String Will do thissussmsraju20:12 20 Nov '03  
GeneralRe: Convert.ToBase64String && Convert.FromBase64String Will do thismemberwchvic22:11 20 Nov '03  
GeneralRe: Convert.ToBase64String && Convert.FromBase64String Will do thismemberhspc5:12 18 May '04  
GeneralRe: Convert.ToBase64String && Convert.FromBase64String Will do thismemberSenFo9:27 24 Jan '07  
GeneralUseful. :)memberJon Rista19:25 20 Nov '03  
GeneralRe: Useful. :)memberwchvic19:32 20 Nov '03  
GeneralRe: Useful. :)memberdog_spawn6:47 21 Nov '03  
GeneralRe: Useful. :)memberChristopher Pietschmann, MCSD, MCAD5:23 3 Feb '05  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 19 Nov 2003
Editor: Nishant Sivakumar
Copyright 2003 by wchvic
Everything else Copyright © CodeProject, 1999-2008
Web07 | Advertise on the Code Project