一. Base64的编码规则
Base64编码的思想是是采用64个基本的ASCII码字符(并不是ascii码的从1-64码的数据,是从中选出的。)对数据进行重新编码。它将需要编码的数据拆分成字节数组。以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),这里的值实际就是数据在字符表中的索引。
注:BASE64字符 表:ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
二.解码 规则
解码过程就是把4个字节再还原成3个字节再根据不同的数据形式把字节数组重新整理 成数据。
三. C#中的实现(2011/03/14)
public class Base64Manager
{
/// <summary>
/// 编码
/// </summary>
/// <param name="sStr">要编码的字符串</param>
/// <returns>编码后的base64格式的字符串</returns>
public string Encoder(string sStr)
{
#region 得到能被3整除的字节数组
byte[] bs = System.Text.Encoding.UTF8.GetBytes(sStr.ToCharArray());
if (bs.Length % 3 == 0)
{
}
else if(bs.Length%3==1)
{
bs = System.Text.Encoding.UTF8.GetBytes((sStr+"==").ToCharArray());
}
else if(bs.Length%3==2)
{
bs = System.Text.Encoding.UTF8.GetBytes((sStr+"=").ToCharArray());
}
#endregion
#region 开始base64编码
byte[] bsLast = new byte[bs.Length / 3 * 4];
char[] c1;
char[] c2;
char[] c3;
char[] c4 = new char[8] { '0', '0', ' ', ' ', ' ', ' ', ' ', ' ' };
char[] c5 = new char[8] { '0', '0', ' ', ' ', ' ', ' ', ' ', ' ' };
char[] c6 = new char[8] { '0', '0', ' ', ' ', ' ', ' ', ' ', ' ' };
char[] c7 = new char[8] { '0', '0', ' ', ' ', ' ', ' ', ' ', ' ' };
char[] c8=new char[24];
for (int i = 0; i < bs.Length; i = i + 3)
{
c1 = change(bs[i]);
c2 = change(bs[i + 1]);
c3 = change(bs[i + 2]);
for (int j = 0; j < 8; j++)
{
c8[j] = c1[j];
c8[j + 8] = c2[j];
c8[j + 16] = c3[j];
}
for (int k = 0; k < 6; k++)
{
c4[k + 2] = c8[k];
c5[k + 2] = c8[k + 6];
c6[k + 2] = c8[k + 12];
c7[k + 2] = c8[k + 18];
}
bsLast[i / 3 * 4 + 0] = (byte)Change2To10(c4);
bsLast[i / 3 * 4 + 1] = (byte)Change2To10(c5);
bsLast[i / 3 * 4 + 2] = (byte)Change2To10(c6);
bsLast[i / 3 * 4 + 3] = (byte)Change2To10(c7);
}
#endregion
return ChangeToBase64Data(bsLast);
}
/// <summary>
/// 解码
/// </summary>
/// <param name="sBase64Data">编码后的base64格式的数据</param>
/// <returns>解码后的数据</returns>
public string Decoder(string sBase64Data)
{
byte[] b = ChangeToByteData(sBase64Data);
char[] c = new char[b.Length / 4 * 3 * 8];
int iState = 0;
foreach (byte bb in b)
{
char[] cc = change(bb);
for (int i = 0; i < 6; i++)
{
c[iState++] = cc[i + 2];
}
}
byte[] bL = new byte[b.Length / 4 * 3];
int iStateOther = 0;
for (int i = 0; i < c.Length / 8; i++)
{
char[] cS = new char[8] { ' ',' ',' ',' ',' ',' ',' ',' '};
for (int j = 0; j < 8; j++)
{
cS[j] = c[i * 8 + j];
}
bL[iStateOther++] = (byte)Change2To10(cS);
}
#region
int iCount = 0;
foreach (byte bbb in bL)
{
if (bbb == (byte)0)
{
iCount++;
}
}
byte[] BLL = new byte[bL.Length - iCount];
for (int i = 0; i < BLL.Length; i++)
{
BLL[i] = bL[i];
}
#endregion
return System.Text.Encoding.UTF8.GetString(BLL);
}
/// <summary>
/// 把变换完的字节数组转换为对应的base64表中的数据
/// </summary>
/// <param name="byt">要转换的字节数组</param>
/// <returns>最终的编码之后的数据</returns>
private string ChangeToBase64Data(byte[] byt)
{
char[] sBase64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".ToCharArray();
string sReturn = "";
foreach (byte b in byt)
{
sReturn += sBase64Table[(Int32)b];
}
return sReturn;
}
/// <summary>
/// 编码后的数据转换为字节数组
/// </summary>
/// <param name="sBase64Data">经过base64编码的数据</param>
/// <returns>编码后的字节数组</returns>
private byte[] ChangeToByteData(string sBase64Data)
{
string sBase64Table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char[] cReturn = new char[sBase64Data.Length];
int iState = 0;
foreach (char c in sBase64Data)
{
cReturn[iState++] = (char)((sBase64Table.IndexOf(c) == -1) ? System.Text.Encoding.UTF8.GetChars(new byte[] { ((byte)0) })[0] : sBase64Table.IndexOf(c));
}
return System.Text.Encoding.UTF8.GetBytes(cReturn);
}
#region 十进制转二进制 <256的数据
/// <summary>
/// 十进制转为二进制数据(传入的数据只能为小于128的整数)
/// </summary>
/// <param name="i10">十进制的数据</param>
/// <returns>转换成的二进制的数组</returns>
private char[] change(int i10)
{
bool state = false;
char[] ch = new char[] { '0', '0', '0', '0', '0', '0', '0', '0' };
int iState = 0;
while (i10 != 0)
{
iState++;
state = false;
if (i10 % 2 == 1)
{
i10 = i10 / 2;
state = true;
}
else
{
i10 = i10 / 2;
}
if (state)
{
ch[8 - iState] = '1';
}
else
{
ch[8 - iState] = '0';
}
}
return ch;
}
/// <summary>
/// 把二进制的八位char数组转为十进制数据
/// </summary>
/// <param name="ch">二进制数据</param>
/// <returns>十进制数</returns>
private int Change2To10(char[] ch)
{
int iReturn = 0;
for (int i = 0; i < 8; i++)
{
if (ch[i] == '1')
{
double d = double.Parse((7 - i).ToString());
iReturn += (Int32)System.Math.Pow(2.0, double.Parse((7 - i).ToString()));
}
}
return iReturn;
}
#endregion
}
浙公网安备 33010602011771号