C#中Base64编码的编码和解码的实现

作者: Nishizhen 分类: C#相关 发布时间: 2010-05-18 13:38 ė 6没有评论

Encoder:

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:

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;
			}

		}

	}
}

使用方式

private void btnEncode_Click(object sender, System.EventArgs e)
		{
			//first get the bytes for the original
			byte[] data=System.Text.UnicodeEncoding.UTF8.GetBytes(txtDecoded.Text);
			Base64Encoder myEncoder=new Base64Encoder(data);
			StringBuilder sb=new StringBuilder();

			sb.Append(myEncoder.GetEncoded());

			txtEncoded.Text=sb.ToString();
		}

		private void btnDecode_Click(object sender, System.EventArgs e)
		{
			char[] data=txtEncoded.Text.ToCharArray();
			Base64Decoder myDecoder=new Base64Decoder(data);
			StringBuilder sb=new StringBuilder();

			byte[] temp=myDecoder.GetDecoded();
			sb.Append(System.Text.UTF8Encoding.UTF8.GetChars(temp));

			txtDecoded.Text=sb.ToString();
		}

本文出自 逆时针's Place,转载时请注明出处及相应链接。

本文永久链接: http://www.nishizhen.cn/c%e4%b8%adbase64%e7%bc%96%e7%a0%81%e7%9a%84%e7%bc%96%e7%a0%81%e5%92%8c%e8%a7%a3%e7%a0%81%e7%9a%84%e5%ae%9e%e7%8e%b0/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

验证码 * Time limit is exhausted. Please reload CAPTCHA.

Ɣ回顶部