Click here to Skip to main content
15,889,877 members
Articles / Programming Languages / C#
Article

Base64 Encoder/Decoder in C#

Rate me:
Please Sign up or sign in to vote.
3.28/5 (47 votes)
19 Nov 2003 367.8K   8.3K   59   35
An implementation of Base64 encoding/decoding in C#

Image 1

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

C#
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

C#
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


Written By
Web Developer
Canada Canada
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionLicense Question Pin
Member 1238613511-Mar-16 10:26
Member 1238613511-Mar-16 10:26 
AnswerRe: License Question Pin
PIEBALDconsult11-Mar-16 10:53
mvePIEBALDconsult11-Mar-16 10:53 
Questioncan someone please explain the shift part in GetEncoded()? Pin
Roy Barina12-Feb-16 7:25
Roy Barina12-Feb-16 7:25 
AnswerRe: can someone please explain the shift part in GetEncoded()? Pin
Roy Barina13-Feb-16 4:42
Roy Barina13-Feb-16 4:42 
QuestionLicense Pin
Alan Hayslep29-Aug-13 0:32
Alan Hayslep29-Aug-13 0:32 
QuestionGreat Pin
RaMMicHaeL22-May-13 10:46
RaMMicHaeL22-May-13 10:46 
QuestionYou are a livesaver Thank you Pin
dl4gbe16-Oct-12 10:13
dl4gbe16-Oct-12 10:13 
GeneralMy vote of 1 Pin
daylightdj1-May-12 1:20
daylightdj1-May-12 1:20 
QuestionOptimized version available on Github Pin
Ramon Smits13-Jan-12 5:43
Ramon Smits13-Jan-12 5:43 
GeneralRe: Optimized version available on Github Pin
ashishkum23-Jan-12 20:53
ashishkum23-Jan-12 20:53 
GeneralMy vote of 5 Pin
Palanikumar3111-Aug-11 23:26
Palanikumar3111-Aug-11 23:26 
GeneralGood, but throws System.OutOfMemoryException when processing large data Pin
joujoukinder27-Apr-11 4:15
joujoukinder27-Apr-11 4:15 
Hello,

Very nice your encoder !

The only problem is that it works on RAM only, and on x86 computers, when processing large data, the process needs to much memory and fires a System.OutOfMemoryException.

The solution is to use file streams instead of the RAM. It will be less quick, but will work for large data.

Actually, I use the encoder to parse email files. When an email has an attachment that is bigger than 30 MB, the encoder crashes.

I wrote my own class, based on yours, that includes files streams.

If you like, you can use / modify it to update this article (The class design is not the best.. Smile | :) ).

Here is the code (partially commented) :

<br />
<br />
using System;<br />
using System.Collections.Generic;<br />
using System.Text;<br />
using System.IO;<br />
<br />
namespace Base64<br />
{<br />
    public abstract class Base64Encoding<br />
    {<br />
        private static char[] lookupTable = new char[64]<br />
					{	'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',<br />
						'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',<br />
						'0','1','2','3','4','5','6','7','8','9','+','/'};<br />
        private static char[] unvalidChars = new char[] { '\r', '\n', '\t' };<br />
        private static Dictionary<char, int> lookupTableDictionnary = new Dictionary<char, int>();<br />
<br />
        private static void BuidLookupTableDictionnary()<br />
        {<br />
            if(lookupTableDictionnary.Count > 0)<br />
                return;<br />
<br />
            for(int i = 0; i < lookupTable.Length; i++)<br />
                lookupTableDictionnary.Add(lookupTable[i], i);<br />
        }<br />
        private static char[] DeleteUnvalidChars(char[] input)<br />
        {<br />
            int numberOfValid = 0;<br />
<br />
            for(int i = 0; i < input.Length; i++)<br />
            {<br />
                if(Array.IndexOf(unvalidChars, input[i]) < 0)<br />
                    numberOfValid++;<br />
            }<br />
            char[] validChars = new char[numberOfValid];<br />
<br />
            for(int i = 0, n = 0; i < input.Length; i++)<br />
            {<br />
                if(Array.IndexOf(unvalidChars, input[i]) < 0)<br />
                {<br />
                    validChars[n] = input[i];<br />
                    n++;<br />
                }<br />
            }<br />
<br />
            return validChars;<br />
        }<br />
<br />
        private static void DeleteUnvalidChars(FileStream inputStream, FileStream ouputStream)<br />
        {<br />
            byte[] b = new byte[1];<br />
<br />
            inputStream.Position = 0;<br />
            ouputStream.Position = 0;<br />
<br />
            while(inputStream.Read(b, 0, 1) > 0)<br />
                if(Array.IndexOf(unvalidChars, (char) b[0]) < 0)<br />
                    ouputStream.Write(b, 0, b.Length);<br />
        }<br />
<br />
        private static byte CharToSixbit(char c)<br />
        {<br />
            if(c == '=')<br />
                return 0;<br />
<br />
            else<br />
            {<br />
                // Use the dictionnary for faster result !<br />
                if(Base64Encoding.lookupTableDictionnary.ContainsKey(c))<br />
                    return (byte) Base64Encoding.lookupTableDictionnary[c];<br />
<br />
                //should not reach here<br />
                return 0;<br />
            }<br />
        }<br />
        private static char SixbitToChar(byte b)<br />
        {<br />
            if((b >= 0) && (b <= 63))<br />
                return lookupTable[(int) b];<br />
            else<br />
                return ' '; //should not happen;<br />
        }<br />
<br />
        public abstract class MemoryEncoding<br />
        {<br />
            /// <summary><br />
            /// Summary description for Base64Encoder.<br />
            /// </summary><br />
            public class MemoryBase64Encoder<br />
            {<br />
                byte[] source;<br />
                int length, length2;<br />
                int blockCount;<br />
                int paddingCount;<br />
<br />
                public MemoryBase64Encoder(string input)<br />
                {<br />
                    byte[] inputBytes = System.Text.Encoding.Default.GetBytes(Base64Encoding.DeleteUnvalidChars(input.ToCharArray()));<br />
                    this.InitEncoder(inputBytes);<br />
                }<br />
<br />
                public MemoryBase64Encoder(byte[] input)<br />
                {<br />
                    this.InitEncoder(input);<br />
                }<br />
<br />
                private void InitEncoder(byte[] input)<br />
                {<br />
                    Base64Encoding.BuidLookupTableDictionnary();<br />
<br />
                    source = input;<br />
                    length = input.Length;<br />
<br />
                    if((length % 3) == 0)<br />
                    {<br />
                        paddingCount = 0;<br />
                        blockCount = length / 3;<br />
                    }<br />
                    else<br />
                    {<br />
                        paddingCount = 3 - (length % 3);//need to add padding<br />
                        blockCount = (length + paddingCount) / 3;<br />
                    }<br />
                    length2 = length + paddingCount;//or blockCount *3<br />
                }<br />
<br />
                public char[] Encode()<br />
                {<br />
                    int i;<br />
<br />
                    byte[] sourceBuffer;<br />
<br />
                    if(length != length2)<br />
                    {<br />
                        sourceBuffer = new byte[length2];<br />
<br />
                        //copy data over insert padding<br />
                        for(i = 0; i < length2; i++)<br />
                        {<br />
                            if(i < length)<br />
                                sourceBuffer[i] = source[i];<br />
                            else<br />
                                sourceBuffer[i] = 0;<br />
                        }<br />
                    }<br />
                    else<br />
                    {<br />
                        sourceBuffer = source;<br />
                    }<br />
<br />
                    byte b1, b2, b3;<br />
                    byte temp, temp1, temp2, temp3, temp4;<br />
                    char[] result = new char[blockCount * 4];<br />
<br />
                    for(i = 0; i < blockCount; i++)<br />
                    {<br />
                        b1 = sourceBuffer[i * 3];<br />
                        b2 = sourceBuffer[i * 3 + 1];<br />
                        b3 = sourceBuffer[i * 3 + 2];<br />
<br />
                        temp1 = (byte) ((b1 & 252) >> 2);//first<br />
<br />
                        temp = (byte) ((b1 & 3) << 4);<br />
                        temp2 = (byte) ((b2 & 240) >> 4);<br />
                        temp2 += temp; //second<br />
<br />
                        temp = (byte) ((b2 & 15) << 2);<br />
                        temp3 = (byte) ((b3 & 192) >> 6);<br />
                        temp3 += temp; //third<br />
<br />
                        temp4 = (byte) (b3 & 63); //fourth<br />
<br />
                        result[i * 4] = Base64Encoding.SixbitToChar(temp1);<br />
                        result[i * 4 + 1] = Base64Encoding.SixbitToChar(temp2);<br />
                        result[i * 4 + 2] = Base64Encoding.SixbitToChar(temp3);<br />
                        result[i * 4 + 3] = Base64Encoding.SixbitToChar(temp4);<br />
                    }<br />
<br />
                    //covert last "A"s to "=", based on paddingCount<br />
                    switch(paddingCount)<br />
                    {<br />
                        case 0:<br />
                            break;<br />
<br />
                        case 1:<br />
<br />
                            result[blockCount * 4 - 1] = '=';<br />
<br />
                            break;<br />
<br />
                        case 2:<br />
<br />
                            result[blockCount * 4 - 1] = '=';<br />
                            result[blockCount * 4 - 2] = '=';<br />
<br />
                            break;<br />
<br />
                        default:<br />
                            break;<br />
                    }<br />
                    return result;<br />
                }<br />
            }<br />
<br />
            /// <summary><br />
            /// Summary description for MemoryBase64Decoder.<br />
            /// </summary><br />
            public class MemoryBase64Decoder<br />
            {<br />
                char[] source;<br />
                int length, length2, length3;<br />
                int blockCount;<br />
                int paddingCount;<br />
<br />
                public MemoryBase64Decoder(string input)<br />
                {<br />
                    char[] inputChars = input.ToCharArray();<br />
                    this.InitDecoder(inputChars);<br />
                }<br />
<br />
                public MemoryBase64Decoder(char[] input)<br />
                {<br />
                    this.InitDecoder(input);<br />
                }<br />
<br />
                private void InitDecoder(char[] input)<br />
                {<br />
                    Base64Encoding.BuidLookupTableDictionnary();<br />
<br />
                    input = Base64Encoding.DeleteUnvalidChars(input);<br />
<br />
                    int temp = 0;<br />
                    source = input;<br />
                    length = input.Length;<br />
<br />
                    //find how many padding are there<br />
                    for(int i = 0; i < 2; i++)<br />
                    {<br />
                        if(input[length - i - 1] == '=')<br />
                            temp++;<br />
                    }<br />
                    paddingCount = temp;<br />
                    //calculate the blockCount;<br />
                    //assuming all whitespace and carriage returns/newline were removed.<br />
                    blockCount = length / 4;<br />
                    length2 = blockCount * 3;<br />
                }<br />
<br />
                public byte[] Decode()<br />
                {<br />
                    byte[] buffer2 = new byte[length2];//decoded array with padding<br />
<br />
                    // Conversion using the source as result<br />
                    for(int i = 0; i < length; i++)<br />
                        source[i] = (char) Base64Encoding.CharToSixbit(source[i]);<br />
<br />
                    byte b, b1, b2, b3;<br />
                    byte temp1, temp2, temp3, temp4;<br />
<br />
                    for(int i = 0; i < blockCount; i++)<br />
                    {<br />
                        temp1 = (byte) source[i * 4];<br />
                        temp2 = (byte) source[i * 4 + 1];<br />
                        temp3 = (byte) source[i * 4 + 2];<br />
                        temp4 = (byte) source[i * 4 + 3];<br />
<br />
                        b = (byte) (temp1 << 2);<br />
                        b1 = (byte) ((temp2 & 48) >> 4);<br />
                        b1 += b;<br />
<br />
                        b = (byte) ((temp2 & 15) << 4);<br />
                        b2 = (byte) ((temp3 & 60) >> 2);<br />
                        b2 += b;<br />
<br />
                        b = (byte) ((temp3 & 3) << 6);<br />
                        b3 = temp4;<br />
                        b3 += b;<br />
<br />
                        buffer2[i * 3] = b1;<br />
                        buffer2[i * 3 + 1] = b2;<br />
                        buffer2[i * 3 + 2] = b3;<br />
                    }<br />
                    //remove paddings<br />
<br />
                    byte[] result = null;<br />
<br />
                    if(paddingCount > 0)<br />
                    {<br />
                        length3 = length2 - paddingCount;<br />
                        result = new byte[length3];<br />
<br />
                        for(int i = 0; i < length3; i++)<br />
                            result[i] = buffer2[i];<br />
                    }<br />
                    else<br />
                    {<br />
                        result = buffer2;<br />
                    }<br />
<br />
                    return result;<br />
                }<br />
            }<br />
        }<br />
        public abstract class FilesEncoding<br />
        {<br />
            /// <summary><br />
            /// Summary description for FilesBase64Encoder.<br />
            /// </summary><br />
            public class FilesBase64Encoder<br />
            {<br />
                private long sourceStreamInitialPosition = -1;<br />
                private long resultStreamInitialPosition = -1;<br />
<br />
                // Open files streams<br />
                private FileStream sourceStream = null; // source<br />
                private FileStream resultStream = null; // result<br />
<br />
                private string inputFilePath = string.Empty;<br />
                private string outputFilePath = string.Empty;<br />
                private string bufferFilePath = string.Empty;<br />
<br />
                long length, length2;<br />
                long blockCount;<br />
                long paddingCount;<br />
<br />
                public FilesBase64Encoder(FileStream inputStream, FileStream outputStream)<br />
                {<br />
                    this.sourceStream = inputStream;<br />
                    this.resultStream = outputStream;<br />
                    this.bufferFilePath = Tools.GetUniqueTempFilePath("B64EncoderBuffer1", ".txt");<br />
<br />
                    this.sourceStreamInitialPosition = sourceStream.Position;<br />
                    this.resultStreamInitialPosition = resultStream.Position;<br />
<br />
                    this.sourceStream.Position = 0;<br />
                    this.resultStream.Position = 0;<br />
<br />
                    this.InitEncoder();<br />
                }<br />
<br />
                public FilesBase64Encoder(string inputFilePath, string outputFilePath)<br />
                {<br />
                    this.inputFilePath = inputFilePath;<br />
                    this.outputFilePath = outputFilePath;<br />
                    this.bufferFilePath = Tools.GetUniqueTempFilePath("B64EncoderBuffer1", ".txt");<br />
<br />
                    this.InitEncoder();<br />
                }<br />
<br />
<br />
                private void InitEncoder()<br />
                {<br />
                    Base64Encoding.BuidLookupTableDictionnary();<br />
<br />
                    if(inputFilePath.Length > 0)<br />
                        sourceStream = new FileStream(inputFilePath, FileMode.Open);<br />
<br />
                    if(outputFilePath.Length > 0)<br />
                        resultStream = new FileStream(outputFilePath, FileMode.Create);<br />
<br />
                    length = sourceStream.Length;<br />
<br />
                    if((length % 3) == 0)<br />
                    {<br />
                        paddingCount = 0;<br />
                        blockCount = length / 3;<br />
                    }<br />
                    else<br />
                    {<br />
                        paddingCount = 3 - (length % 3);//need to add padding<br />
                        blockCount = (length + paddingCount) / 3;<br />
                    }<br />
<br />
                    length2 = length + paddingCount;//or blockCount *3<br />
                }<br />
<br />
                public void Encode()<br />
                {<br />
                    FileStream sourceBufferStream = null; // sourceBuffer<br />
<br />
                    try<br />
                    {<br />
                        if(length != length2)<br />
                        {<br />
                            sourceBufferStream = new FileStream(bufferFilePath, FileMode.Create);<br />
<br />
                            //copy data over insert padding<br />
                            for(int i = 0; i < length2; i++)<br />
                            {<br />
                                if(i < length)<br />
                                    sourceBufferStream.WriteByte((byte) sourceStream.ReadByte());<br />
                                else<br />
                                    sourceBufferStream.WriteByte((byte) 0);<br />
                            }<br />
                        }<br />
                        else<br />
                        {<br />
                            sourceBufferStream = sourceStream;<br />
                        }<br />
<br />
                        sourceBufferStream.Position = 0;<br />
<br />
                        byte[] threeBytes = new byte[3];<br />
                        byte temp, temp1, temp2, temp3, temp4;<br />
                        for(int i = 0; i < blockCount; i++)<br />
                        {<br />
                            sourceBufferStream.Read(threeBytes, 0, threeBytes.Length);<br />
<br />
                            temp1 = (byte) ((threeBytes[0] & 252) >> 2);//first<br />
<br />
                            temp = (byte) ((threeBytes[0] & 3) << 4);<br />
                            temp2 = (byte) ((threeBytes[1] & 240) >> 4);<br />
                            temp2 += temp; //second<br />
<br />
                            temp = (byte) ((threeBytes[1] & 15) << 2);<br />
                            temp3 = (byte) ((threeBytes[2] & 192) >> 6);<br />
                            temp3 += temp; //third<br />
<br />
                            temp4 = (byte) (threeBytes[2] & 63); //fourth<br />
<br />
<br />
                            resultStream.WriteByte((byte) Base64Encoding.SixbitToChar(temp1));<br />
                            resultStream.WriteByte((byte) Base64Encoding.SixbitToChar(temp2));<br />
                            resultStream.WriteByte((byte) Base64Encoding.SixbitToChar(temp3));<br />
                            resultStream.WriteByte((byte) Base64Encoding.SixbitToChar(temp4));<br />
                        }<br />
<br />
                        //covert last "A"s to "=", based on paddingCount<br />
                        switch(paddingCount)<br />
                        {<br />
                            case 0:<br />
                                break;<br />
<br />
                            case 1:<br />
<br />
                                resultStream.Position = resultStream.Length - 1;<br />
                                resultStream.Write(new byte[] { (byte) '=' }, 0, 1);<br />
<br />
                                break;<br />
<br />
                            case 2:<br />
<br />
                                resultStream.Position = resultStream.Length - 1;<br />
                                resultStream.Write(new byte[] { (byte) '=' }, 0, 1);<br />
<br />
                                resultStream.Position = resultStream.Length - 2;<br />
                                resultStream.Write(new byte[] { (byte) '=' }, 0, 1);<br />
<br />
                                break;<br />
<br />
                            default:<br />
                                break;<br />
                        }<br />
                    }<br />
                    finally<br />
                    {<br />
                        this.sourceStreamInitialPosition = sourceStream.Position;<br />
                        this.resultStreamInitialPosition = resultStream.Position;<br />
<br />
                        if(inputFilePath.Length > 0)<br />
                        {<br />
                            if(sourceStream != null)<br />
                                sourceStream.Close();<br />
                        }<br />
                        else<br />
                        {<br />
                            this.sourceStream.Position = this.sourceStreamInitialPosition;<br />
                        }<br />
<br />
                        if(outputFilePath.Length > 0)<br />
                        {<br />
                            if(resultStream != null)<br />
                                resultStream.Close();<br />
                        }<br />
                        else<br />
                        {<br />
                            this.resultStream.Position = this.resultStreamInitialPosition;<br />
                        }<br />
<br />
                        if(sourceBufferStream != null)<br />
                            if(sourceBufferStream != sourceStream)<br />
                                sourceBufferStream.Close();<br />
<br />
                        if(File.Exists(bufferFilePath))<br />
                            File.Delete(bufferFilePath);<br />
                    }<br />
                }<br />
            }<br />
<br />
            /// <summary><br />
            /// Summary description for FilesBase64Decoder.<br />
            /// </summary><br />
            public class FilesBase64Decoder<br />
            {<br />
                private long sourceStreamInitialPosition = -1;<br />
                private long resultStreamInitialPosition = -1;<br />
<br />
                private string inputFilePath = string.Empty;<br />
                private string outputFilePath = string.Empty;<br />
                private string bufferFilePath1 = string.Empty;<br />
                private string bufferFilePath2 = string.Empty;<br />
<br />
                private FileStream sourceStream = null; // source<br />
                private FileStream resultStream = null; // result<br />
<br />
                long length, length2, length3;<br />
                long blockCount;<br />
                long paddingCount;<br />
<br />
                public FilesBase64Decoder(string inputFilePath, string outputFilePath)<br />
                {<br />
                    this.inputFilePath = inputFilePath;<br />
                    this.outputFilePath = outputFilePath;<br />
                    this.bufferFilePath1 = Tools.GetUniqueTempFilePath("B64EncoderBuffer1", ".txt");<br />
                    this.bufferFilePath2 = Tools.GetUniqueTempFilePath("B64EncoderBuffer2", ".txt");<br />
<br />
                    this.InitDecoder();<br />
                }<br />
<br />
                public FilesBase64Decoder(FileStream inputStream, FileStream outputStream)<br />
                {<br />
                    this.sourceStream = inputStream;<br />
                    this.resultStream = outputStream;<br />
                    this.bufferFilePath1 = Tools.GetUniqueTempFilePath("B64EncoderBuffer1", ".txt");<br />
                    this.bufferFilePath2 = Tools.GetUniqueTempFilePath("B64EncoderBuffer2", ".txt");<br />
<br />
                    this.sourceStreamInitialPosition = this.sourceStream.Position;<br />
                    this.resultStreamInitialPosition = this.resultStream.Position;<br />
<br />
                    this.sourceStream.Position = 0;<br />
                    this.resultStream.Position = 0;<br />
<br />
                    this.InitDecoder();<br />
                }<br />
<br />
                private void InitDecoder()<br />
                {<br />
                    Base64Encoding.BuidLookupTableDictionnary();<br />
<br />
                    if(inputFilePath.Length > 0)<br />
                        sourceStream = new FileStream(inputFilePath, FileMode.Open);<br />
<br />
                    if(outputFilePath.Length > 0)<br />
                        resultStream = new FileStream(outputFilePath, FileMode.Create);<br />
<br />
                    FileStream sourceBufferStream = null;<br />
<br />
                    try<br />
                    {<br />
                        sourceBufferStream = new FileStream(bufferFilePath1, FileMode.Create);<br />
                        Base64Encoding.DeleteUnvalidChars(sourceStream, sourceBufferStream);<br />
<br />
                        int temp = 0;<br />
                        length = sourceBufferStream.Length;<br />
<br />
                        byte[] tempByteArray = new byte[1];<br />
<br />
                        //find how many padding are there<br />
                        for(int i = 0; i < 2; i++)<br />
                        {<br />
                            sourceBufferStream.Position = length - i - 1;<br />
                            sourceBufferStream.Read(tempByteArray, 0, 1);<br />
<br />
                            if(tempByteArray[0] == '=')<br />
                                temp++;<br />
                        }<br />
<br />
                        paddingCount = temp;<br />
                        //calculate the blockCount;<br />
                        //assuming all whitespace and carriage returns/newline were removed.<br />
                        blockCount = length / 4;<br />
                        length2 = blockCount * 3;<br />
                    }<br />
                    finally<br />
                    {<br />
                        if(sourceBufferStream != null)<br />
                            sourceBufferStream.Close();<br />
                    }<br />
                }<br />
<br />
                public void Decode()<br />
                {<br />
                    FileStream sourceBufferStream1 = null;<br />
                    FileStream sourceBufferStream2 = null;<br />
<br />
                    try<br />
                    {<br />
                        sourceBufferStream1 = new FileStream(bufferFilePath1, FileMode.Open);<br />
                        sourceBufferStream2 = new FileStream(bufferFilePath2, FileMode.Create);<br />
<br />
                        byte[] buffer2 = new byte[length2];//decoded array with padding<br />
                        byte[] tempByteArray = new byte[1];<br />
<br />
                        sourceBufferStream1.Position = 0;<br />
<br />
                        // Conversion using the source as result<br />
                        for(int i = 0; i < length; i++)<br />
                        {<br />
                            sourceBufferStream1.Read(tempByteArray, 0, 1);<br />
                            tempByteArray[0] = Base64Encoding.CharToSixbit((char) tempByteArray[0]);<br />
                            sourceBufferStream2.Write(tempByteArray, 0, 1);<br />
                        }<br />
<br />
                        if(sourceBufferStream1 != null)<br />
                            sourceBufferStream1.Close();<br />
<br />
                        sourceBufferStream2.Position = 0;<br />
<br />
                        sourceBufferStream1 = new FileStream(bufferFilePath1, FileMode.Create);<br />
<br />
                        byte[] fourBytes = new byte[4];<br />
<br />
                        byte b, b1, b2, b3;<br />
                        byte temp1, temp2, temp3, temp4;<br />
<br />
                        for(int i = 0; i < blockCount; i++)<br />
                        {<br />
                            sourceBufferStream2.Read(fourBytes, 0, fourBytes.Length);<br />
<br />
                            temp1 = fourBytes[0];<br />
                            temp2 = fourBytes[1];<br />
                            temp3 = fourBytes[2];<br />
                            temp4 = fourBytes[3];<br />
<br />
                            b = (byte) (temp1 << 2);<br />
                            b1 = (byte) ((temp2 & 48) >> 4);<br />
                            b1 += b;<br />
<br />
                            b = (byte) ((temp2 & 15) << 4);<br />
                            b2 = (byte) ((temp3 & 60) >> 2);<br />
                            b2 += b;<br />
<br />
                            b = (byte) ((temp3 & 3) << 6);<br />
                            b3 = temp4;<br />
                            b3 += b;<br />
<br />
                            sourceBufferStream1.WriteByte(b1);<br />
                            sourceBufferStream1.WriteByte(b2);<br />
                            sourceBufferStream1.WriteByte(b3);<br />
                        }<br />
<br />
                        sourceBufferStream1.Position = 0;<br />
<br />
                        //remove paddings<br />
                        if(paddingCount > 0)<br />
                        {<br />
                            length3 = length2 - paddingCount;<br />
<br />
                            for(int i = 0; i < length3; i++)<br />
                                resultStream.WriteByte((byte) sourceBufferStream1.ReadByte());<br />
                        }<br />
                        else<br />
                        {<br />
                            for(int i = 0; i < length2; i++)<br />
                                resultStream.WriteByte((byte) sourceBufferStream1.ReadByte());<br />
                        }<br />
                    }<br />
                    finally<br />
                    {<br />
                        if(inputFilePath.Length > 0)<br />
                        {<br />
                            if(sourceStream != null)<br />
                                sourceStream.Close();<br />
                        }<br />
                        else<br />
                        {<br />
                            this.sourceStream.Position = this.sourceStreamInitialPosition;<br />
                        }<br />
                        if(outputFilePath.Length > 0)<br />
                        {<br />
                            if(resultStream != null)<br />
                                resultStream.Close();<br />
                        }<br />
                        else<br />
                        {<br />
                            this.resultStream.Position = this.resultStreamInitialPosition;<br />
                        }<br />
<br />
                        if(sourceBufferStream1 != null)<br />
                            sourceBufferStream1.Close();<br />
<br />
                        if(sourceBufferStream2 != null)<br />
                            sourceBufferStream2.Close();<br />
<br />
                        if(File.Exists(bufferFilePath1))<br />
                            File.Delete(bufferFilePath1);<br />
<br />
                        if(File.Exists(bufferFilePath2))<br />
                            File.Delete(bufferFilePath2);<br />
                    }<br />
                }<br />
            }<br />
        }<br />
    }<br />
<br />
    public abstract class Tools<br />
    {<br />
        public static string GetUniqueTempFilePath(string beginWith, string fileExtension)<br />
        {<br />
            // Attendre une milliseconde pour être sûrs de l'unicité de nom de fichier<br />
            System.Threading.Thread.Sleep(1);<br />
            return Path.Combine(Path.GetTempPath(), GetUniqueTempFileName(beginWith, fileExtension));<br />
        }<br />
<br />
        public static string GetUniqueTempFileName(string beginWith, string fileExtension)<br />
        {<br />
            // Attendre une milliseconde pour être sûrs de l'unicité de nom de fichier<br />
            System.Threading.Thread.Sleep(1);<br />
<br />
            return beginWith + " " + GetDateString(DateTime.Now) + fileExtension;<br />
        }<br />
<br />
        public static string GetDateString(DateTime d)<br />
        {<br />
            return d.Year.ToString() + "_"<br />
                       + d.Month.ToString() + "_"<br />
                       + d.Day.ToString() + "_"<br />
                       + d.Hour.ToString() + "_"<br />
                       + d.Minute.ToString() + "_"<br />
                       + d.Second.ToString() + "_"<br />
                       + d.Millisecond.ToString();<br />
<br />
        }<br />
    }<br />
}<br />
<br />
<br />


I hope this helps people having the same issue.

Best regards.
joujoukinder

GeneralMy vote of 5 Pin
Jason Newland8-Apr-11 17:34
Jason Newland8-Apr-11 17:34 
GeneralMy vote of 2 Pin
Toli Cuturicu22-Oct-10 8:31
Toli Cuturicu22-Oct-10 8:31 
GeneralRe: My vote of 2 Pin
Jason Newland8-Apr-11 17:38
Jason Newland8-Apr-11 17:38 
GeneralRe: My vote of 2 Pin
TheDarkPT24-May-14 7:05
TheDarkPT24-May-14 7:05 
GeneralVery inefficient encoder Pin
andykernahan29-Jun-07 23:06
andykernahan29-Jun-07 23:06 
GeneralRe: Very inefficient encoder Pin
TimmMartin27-Feb-08 3:56
TimmMartin27-Feb-08 3:56 
GeneralC#.NET Window applicaiton Pin
crish_fn21-Feb-07 8:41
crish_fn21-Feb-07 8:41 
Generaldecoding is broken if there are linefeeds Pin
no_way20-Feb-07 20:08
no_way20-Feb-07 20:08 
GeneralThanks for the code Pin
WillStay7-Oct-06 3:18
WillStay7-Oct-06 3:18 
GeneralReally useful in mail subject decoding Pin
Raja K Vairakkannu22-Aug-06 4:07
Raja K Vairakkannu22-Aug-06 4:07 
JokeReliable than .NET version! Thanks Pin
meraydin21-Jun-06 20:31
meraydin21-Jun-06 20:31 
GeneralRe: Reliable than .NET version! Thanks Pin
SenFo24-Jan-07 10:01
SenFo24-Jan-07 10:01 
GeneralVery Useful - especially if you want to implement a base 64 encoder for URL Pin
monkeydispenser17-Mar-06 1:44
monkeydispenser17-Mar-06 1:44 

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

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.