虽然有在线工具,但是原理这东西还是都要明白才行,不然换汤不换药就不会了噢
base64原理
简单来说就是——“把3个字节变成4个字节”
这么说吧,3个字节一共24个bit
,把这24个bit
依次分成4个组,每个组6个bit
,再把这6个bit
塞到一个字节中去(最高位补两个0就变成8个bit
),就会变成4个字节。没了。
因为6个bit
最多能表示26=6426=64,也就是说Base64编码出来的字符种类只有64个,这也是Base64名字的由来。
应用
- 由于二进制的一些字符在网络协议中属于控制字符,不能直接传送,因此需要用Base64编码之后传输,编码之后传输的是一些很普通的ASCII字符。
- Base64常用于邮件编码,当邮件中有二进制数据时,就要编码转换。
- 图片的编码
- Url中有二进制数据,这个时候需要Base64编码(Web安全的Base64)
- 可以进行简单的加密,Base64的编解码规则是透明的,因此用Base64加密时要加盐。
映射表Alphabet
(图自维基百科)
图解
(图自https://baijiahao.baidu.com/s?id=1644892102150918183&wfr=spider&for=pc)
对重组后的数据处理,每组最前面添加两个“0”,构成每组8个bit。由于在最前面添加的0,所以对数值不构成影响。
这里要注意其实严格上来说base64并不属于加密,只是为了方便传输而已。
到这里你可能会发现貌似只有字节数是3的倍数才能处理啊,那么现实情况中,不是3的倍数的情况多的是,怎么办?
方法::补零加 “=”
号(2个0为一个=)
(图自https://blog.csdn.net/flushhip/article/details/82498670)
因此Base64编码后有时候可以看到=
或者==
这都是正常的。
那么解码的密文就有一定的要求的,从前面的分析中得出来,加密之后形成的密文长度一定是4的倍数,且字符串中的字符一定要在映射表中,或者字符为=
,还有,只可能有一个=
或一个==
。
C++实现base64编码
主要用的是位运算:
/*Encode*/
// 0 index byte
index = _group[0] >> 2;
_buf.push_back(_encodeMap[index]);
// 1 index byte
index = ((_group[0] & 0x03) << 4) | (_group[1] >> 4);
_buf.push_back(_encodeMap[index]);
// 2 index byte
index = ((_group[1] & 0x0F) << 2) | (_group[2] >> 6);
_buf.push_back(_encodeMap[index]);
// 3 index byte
index = _group[2] & 0x3F;
_buf.push_back(_encodeMap[index]);
解码关键代码:
/*Decode*/
buff[0] = (_decodeMap[_group[0]] << 2) | (_decodeMap[_group[1]] >> 4);
if (_group[2] != '=')
{
buff[1] = ((_decodeMap[_group[1]] & 0x0F) << 4) | (_decodeMap[_group[2]] >> 2);
top = 2;
}
if (_group[3] != '=')
{
buff[2] = (_decodeMap[_group[2]] << 6) | _decodeMap[_group[3]];
top = 3;
}
for (unsigned int i = 0; i < top; ++i)
{
_buf.push_back(buff[i]);
}
完整代码这里就不放出来了,放个传送门上来。
我之前做题的时候就有遇到过换了映射表的base64,其实这就是典型的换汤不换药,不过用在线工具解肯定就不行了,还是要自己写个脚本,如果你理解了上面的原理的话其实这个就不是很难啦
具体例题和脚本见该博客
如果是写脚本解码的话可以直接用python的base64库,然后用base64.b64decode(xxx)函数直接解,具体在这里就不做详解了,可以自己去看一下python的知识。