Base64编码与解码

1、Base64是什么
  Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。Base64一般用于在 HTTP协议下传输二进制数据,由于 HTTP协议是文本协议,所以在 HTTP协议下传输二进制数据需要将二进制数据转换为字符数据。然而直接转换是不行的。因为网络传输只能传输可打印字符。 什么是可打印字符?在ASCII码中规定,0-31、127这33个字符属于控制字符,32~126这95个字符属于可打印字符,也就是说网络传输只能传输这95个字符,不在这个范围内的字符无法传输。那么该怎么才能传输其他字符呢?其中一种方式就是使用Base64。
  
2、Base64的编码规则
  BASE64字符表:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
  Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码。它将需要编码的数据拆分成字节数组。以3个字节为一组。按顺序排列24 位数据,再把这24位数据分成4组,即每组6位。再在每组的的最高位前补两个0凑足一个字节。这样就把一个3字节为一组的数据重新编码成了4个字节。当所要编码的数据的字节数不是3的整倍数,也就是说在分组时最后一组不够3个字节。这时在最后一组填充1到2个0字节。并在最后编码完成后在结尾添加1到2个 “=”。

例:将对ABC进行BASE64编码:
1、首先取ABC对应的ASCII码值。A(65)B(66)C(67);
2、再取二进制值A(01000001)B(01000010)C(01000011);
3、然后把这三个字节的二进制码接起来(010000010100001001000011);
4、 再以6位为单位分成4个数据块,并在最高位填充两个0后形成4个字节的编码后的值,(00010000)(00010100)(00001001)(00000011),其中蓝色部分为真实数据;
5、再把这四个字节数据转化成10进制数得(16)(20)(9)(3);
6、最后根据BASE64给出的64个基本字符表,查出对应的ASCII码字符(Q)(U)(J)(D),这里的值实际就是数据在字符表中的索引。

3、解码规则
  解码过程就是把4个字节再还原成3个字节再根据不同的数据形式把字节数组重新整理成数据。
  
4、C#代码实现

	static string base64encode_tbl = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	static byte[] base64decode_tbl =
	{
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
		0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0, 
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,62, 0, 0, 0,63,
		52,53,54,55,56,57,58,59,60,61, 0, 0, 0, 0, 0, 0,
		0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
		15,16,17,18,19,20,21,22,23,24,25, 0, 0, 0, 0, 0,
		0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
		41,42,43,44,45,46,47,48,49,50,51
	};

	public static string base64_encode(byte[] data)
	{
		StringBuilder sb = new StringBuilder();
		byte[] cTemp = { 0, 0, 0 };
		int len = data.Length;
		int iDiv3Num = len / 3;
		int iMod3Num = len % 3;

		int line_len = 0;
		int idx = 0;

		for (int i = 0; i < iDiv3Num; i++)
		{
			cTemp[0] = data[idx++];
			cTemp[1] = data[idx++];
			cTemp[2] = data[idx++];

			sb.Append(base64encode_tbl[cTemp[0] >> 2]);
			sb.Append(base64encode_tbl[((cTemp[0] << 4) | (cTemp[1] >> 4)) & 0x3F]);
			sb.Append(base64encode_tbl[((cTemp[1] << 2) | (cTemp[2] >> 6)) & 0x3F]);
			sb.Append(base64encode_tbl[cTemp[2] & 0x3F]);

			line_len += 4;
			if (line_len == 76)
			{
				sb.Append("\r\n");
				line_len = 0;
			}
		}

		if (iMod3Num == 1)
		{
			cTemp[0] = data[idx++];
			sb.Append(base64encode_tbl[(cTemp[0] & 0xFC) >> 2]);
			sb.Append(base64encode_tbl[(cTemp[0] & 0x03) << 4]);
			sb.Append("==");
		}
		else if (iMod3Num == 2)
		{
			cTemp[0] = data[idx++];
			cTemp[1] = data[idx++];

			sb.Append(base64encode_tbl[(cTemp[0] & 0xFC) >> 2]);
			sb.Append(base64encode_tbl[((cTemp[0] & 0x03) << 4) | ((cTemp[1] & 0xF0) >> 4)]);
			sb.Append(base64encode_tbl[((cTemp[1] & 0x0F) << 2)]);
            sb.Append("=");
		}

		return sb.ToString();
	}

	public static byte[] base64_decode(string d_in)
	{
		byte[] data = System.Text.Encoding.UTF8.GetBytes(d_in);
		int len = data.Length;

		MemoryStream ms = new MemoryStream();
		BinaryWriter bw = new BinaryWriter(ms);

		int nValue;
		int i = 0;

		int idx = 0;

		while (i < len)
		{
			if (data[idx] == '\r' || data[idx] == '\n')
			{
				idx++;
				i++;
				continue;
			}

			nValue = (int)(base64decode_tbl[data[idx++]] << 18);
			nValue += (int)(base64decode_tbl[data[idx++]] << 12);

			int c3 = (nValue & 0x00FF0000) >> 16;
			bw.Write((byte)c3);

			if (data[idx] != '=')
			{
				nValue += (int)(base64decode_tbl[data[idx++]] << 6);
				int c4 = (nValue & 0x0000FF00) >> 8;
				bw.Write((byte)c4);

				if (data[idx] != '=')
				{
					nValue += (int)(base64decode_tbl[data[idx++]]);
					int c5 = nValue & 0x000000FF;
					bw.Write((byte)c5);
				}
			}

			i += 4;
		}

		return ms.ToArray();
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值