asp.net Base64 编码与解码程序

作者:袖梨 2022-06-25
一. 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
    {
        ///
        /// 编码
        ///

        /// 要编码的字符串
        /// 编码后的base64格式的字符串
        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);
        }
        ///
        /// 解码
        ///

        /// 编码后的base64格式的数据
        /// 解码后的数据
        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);
        }
        ///
        /// 把变换完的字节数组转换为对应的base64表中的数据
        ///

        /// 要转换的字节数组
        /// 最终的编码之后的数据
        private string changetobase64data(byte[] byt)
        {
            char[] sbase64table = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789+/".tochararray();
            string sreturn = "";
            foreach (byte b in byt)
            {
                sreturn += sbase64table[(int32)b];
            }
            return sreturn;
        }
        ///
        /// 编码后的数据转换为字节数组
        ///

        /// 经过base64编码的数据
        /// 编码后的字节数组
        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的数据
        ///
        /// 十进制转为二进制数据(传入的数据只能为小于128的整数)
        ///

        /// 十进制的数据
        /// 转换成的二进制的数组
        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;
        }
        ///
        /// 把二进制的八位char数组转为十进制数据
        ///

        /// 二进制数据
        /// 十进制数
        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
    }

相关文章

精彩推荐