Base64 加解密

1.

 举一个具体的实例,演示英语单词Man如何转成Base64编码。

Text content M a n
ASCII 77 97 110
Bit pattern 0 1 0 0 1 1 0 1 0 1 1 0 0 0 0 1 0 1 1 0 1 1 1 0
Index 19 22 5 46
Base64-Encoded T W F u

第一步,“M”、“a”、“n”的ASCII值分别是77、97、110,对应的二进制值是01001101、01100001、01101110,将它们连成一个24位的二进制字符串010011010110000101101110。

第二步,将这个24位的二进制字符串分成4组,每组6个二进制位:010011、010110、000101、101110。

第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节:00010011、00010110、00000101、00101110。它们的十进制值分别是19、22、5、46。

第四步,根据上表,得到每个值对应Base64编码,即T、W、F、u。

因此,Man的Base64编码就是TWFu。

2.

如果字节数不足三,则这样处理:

a)二个字节的情况:将这二个字节的一共16个二进制位,按照上面的规则,转成三组,最后一组除了前面加两个0以外,后面也要加两个0。这样得到一个三位的Base64编码,再在末尾补上一个“=”号。

比如,“Ma”这个字符串是两个字节,可以转化成三组00010011、00010110、00010000以后,对应Base64值分别为T、W、E,再补上一个“=”号,因此“Ma”的Base64编码就是TWE=。

b)一个字节的情况:将这一个字节的8个二进制位,按照上面的规则转成二组,最后一组除了前面加二个0以外,后面再加4个0。这样得到一个二位的Base64编码,再在末尾补上两个“=”号。

比如,“M”这个字母是一个字节,可以转化为二组00010011、00010000,对应的Base64值分别为T、Q,再补上二个“=”号,因此“M”的Base64编码就是TQ==。

3.

再举一个中文的例子,汉字“严”如何转化成Base64编码?

这里需要注意,汉字本身可以有多种编码,比如gb2312、utf-8、gbk等等,每一种编码的Base64对应值都不一样。下面的例子以utf-8为例。

首先,“严”的utf-8编码为E4B8A5,写成二进制就是三字节的“11100100 10111000 10100101”。将这个24位的二进制字符串,按照第3节中的规则,转换成四组一共32位的二进制值“00111001 00001011 00100010 00100101”,相应的十进制数为57、11、34、37,它们对应的Base64值就为5、L、i、l。

所以,汉字“严”(utf-8编码)的Base64值就是5Lil。

一、编码规则
Base64编码的思想是是采用64个基本的ASCII码字符对数据进行重新编码。它将需要编码的数据拆分成字节

数组。以3个字节为一组。按顺序排列24 位数据,再把这24位数据分成4组,即每组6位。再在每组的的最高位前

补两个0凑足一个字节。这样就把一个3字节为一组的数据重新编码成了4个字节。当所要编码的数据的字节数不是

3的整倍数,也就是说在分组时最后一组不够3个字节。这时在最后一组填充2到4个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#中的实现

private string Encode64(string Message)

{

    char[] Base64Code = new char[]

      {

        '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', '+', '/', '='

      };

    byte empty = (byte)0;

    System.Collections.ArrayList byteMessage = new

      System.Collections.ArrayList(System.Text.Encoding.Default.GetBytes

      (Message));

    System.Text.StringBuilder outmessage;

    int messageLen = byteMessage.Count;

    int page = messageLen / 3;

    int use = 0;

    if ((use = messageLen % 3) > 0)

    {

        for (int i = 0; i < 3 - use; i++)

            byteMessage.Add(empty);

        page++;

    }

    outmessage = new System.Text.StringBuilder(page * 4);

    for (int i = 0; i < page; i++)

    {

        byte[] instr = new byte[3];

        instr[0] = (byte)byteMessage[i * 3];

        instr[1] = (byte)byteMessage[i * 3 + 1];

        instr[2] = (byte)byteMessage[i * 3 + 2];

        int[] outstr = new int[4];

        outstr[0] = instr[0] >> 2;

        outstr[1] = ((instr[0] & 0x03) << 4) ^ (instr[1] >> 4);

        if (!instr[1].Equals(empty))

            outstr[2] = ((instr[1] & 0x0f) << 2) ^ (instr[2] >> 6);

        else

            outstr[2] = 64;

        if (!instr[2].Equals(empty))

            outstr[3] = (instr[2] & 0x3f);

        else

            outstr[3] = 64;

        outmessage.Append(Base64Code[outstr[0]]);

        outmessage.Append(Base64Code[outstr[1]]);

        outmessage.Append(Base64Code[outstr[2]]);

        outmessage.Append(Base64Code[outstr[3]]);

    }

    return outmessage.ToString();

}



private string Decode64(string Message)

{

  string Base64Code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

  int page = Message.Length / 4;

  System.Collections.ArrayList outMessage = new System.Collections.ArrayList(page * 3);

  char[]message = Message.ToCharArray();

  for (int i = 0; i < page; i++)

  {

    byte[]instr = new byte[4];

    instr[0] = (byte)Base64Code.IndexOf(message[i * 4]);

    instr[1] = (byte)Base64Code.IndexOf(message[i * 4+1]);

    instr[2] = (byte)Base64Code.IndexOf(message[i * 4+2]);

    instr[3] = (byte)Base64Code.IndexOf(message[i * 4+3]);

    byte[]outstr = new byte[3];

    outstr[0] = (byte)((instr[0] << 2) ^ ((instr[1] & 0x30) >> 4));

    if (instr[2] != 64)

    {

      outstr[1] = (byte)((instr[1] << 4) ^ ((instr[2] & 0x3c) >> 2));

    }

    else

    {

      outstr[2] = 0;

    }

    if (instr[3] != 64)

    {

      outstr[2] = (byte)((instr[2] << 6) ^ instr[3]);

    }

    else

    {

      outstr[2] = 0;

    }

    outMessage.Add(outstr[0]);

    if (outstr[1] != 0)

      outMessage.Add(outstr[1]);

    if (outstr[2] != 0)

      outMessage.Add(outstr[2]);

  }

  byte[]outbyte = (byte[])outMessage.ToArray(Type.GetType("System.Byte"));

  return System.Text.Encoding.Default.GetString(outbyte);

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值