欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Base64加密原理

程序员文章站 2024-02-05 11:57:16
...

Base64加密方式是将三个八位的字节转化为四个六位的字节(不足八位的高位补00),3*8 = 4*6;,所以base64加密过后的内容比原来的大三分之一;

举例:加密“ace”,

ace转化为二进制为:‭01100001‬ ‭01100011‬ ‭01100101‬

转化为base64的四字节六位:011000 01‬‭0110 0011‬01 100101‬

那因为计算机是一字节八位的存数,所以高位补00后变为:00011000 0001‬‭0110 000011‬01 00100101‬

转化为十进制:24 22 13 37

查Base64对照表(默认版本RFC2045):

Base64加密原理

我们得到最终结果:YWNl

我们观察这个对照表,大小写的字母26*2 加上10个数字 加上两个特殊符号 + / 一共64个字符,因为Base64有效位只有六位,所以最大能表示的字符就为2的6次方64;

例子中为了方便演示我只取了三个字节的字符串,实际中会存在字节数量不是3倍数的情况,Base64是这样处理的:

剩余的字节根据编码规则继续单独转(不够的位数用0补全),再用=号补满4个字节。这就是为什么有些Base64编码会以一个或两个等号结束的原因,但等号最多只有两个。因为:

一个原字节至少会变成两个目标字节(原字节八位,目标字节六位),两个原字节至少会变成三个目标字节;

所以如果余数为1的话,转成2个Base64编码字符,这个时候我们需要补2个等号;如果余数为2的话,转成3个Base64编码字符,这个时候我们需要补1个等号;

接下来附上java中编码实现Base64转换(java中已经有实现了完整功能的Base64类,所以不用重复造*,例子只实现最核心Base64加密原理):

private static final byte ENCODE[] = {
            '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', '+', '/',
    };

    public static String encode(String str){
        byte[] bytes = str.getBytes();
        String result1 = Base64.encodeToString(bytes, Base64.DEFAULT);
        int temp = ((bytes[0] & 0xff) << 16) | ((bytes[1] & 0xff) << 8) | ((bytes[2] & 0xff));
        int char1 = (temp>>18 & 0x3f);
        int char2 = (temp>>12 & 0x3f);
        int char3 = (temp>>6 & 0x3f);
        int char4 = (temp & 0x3f);
        String result2 = new String(new byte[]{ENCODE[char1],ENCODE[char2],ENCODE[char3],ENCODE[char4]});
        LogUtil.i(result1 +""+result2);
        return result2;
    }

结果:

Base64加密原理

附:

标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符。

为解决此问题,可采用一种用于URL的改进Base64编码,它不仅在末尾去掉填充的'='号,并将标准Base64中的“+”和“/”分别改成了“-”和“_”,这样就免去了在URL编解码和数据库存储时所要作的转换。

更多Base64规则参考:http://www.ietf.org/rfc/rfc2045.txt