Base64编码原理详解:3字节变4字符到底怎么转

liuzw 34 0

前端调接口传二进制、邮件附件、data URL图片、JWT那三段,到处都是Base64那串以等号结尾的字符串。但真问起来为啥3字节变4字符、那两个等号哪来的、64这个数怎么定的,能答全的不多。其实Base64原理很直白,拆成二进制位一看就懂。

为什么是64

Base64要解决的问题是:把任意二进制数据用可打印的ASCII字符表示出来,方便在只认文本的渠道里传输。它选了64个安全字符,就是大小写字母各26个共52个,加数字10个共62个,再加加号和斜杠两个符号,凑成64个。64等于2的6次方,也就是说每个字符能表示6位二进制信息。

关键来了。原始数据是按字节也就是8位组织的,Base64字符按6位组织,8和6的最小公倍数是24,也就是3个字节正好等于4个Base64字符,24位刚好整分。所以Base64的规则是把每3个字节一组,共24位,重新切成4组每组6位,每组6位映射成一个字符。这就是3变4的由来。

编码过程一步步拆

拿三个字节举例,假设十六进制是41 42 43,也就是ABC的ASCII。转成二进制是24位:01000001 01000010 01000011。重新按6位切分,得到四组:010000、010100、001001、000011。每组转成十进制是16、20、9、3。去Base64字符表里查,索引16是Q,20是U,9是J,3是D。所以ABC编码后是QUJD。这就是Base64编码的完整过程,说白了就是位重组加查表。

任何长度的数据都按这个规则走。能被3整除的部分直接转,最后多出来1个或2个字节单独处理。

等号填充怎么回事

如果原始数据字节数不是3的倍数,最后会剩1个或2个字节,凑不成完整的4字符组,这时候就用等号填充。剩1个字节8位,前面补0凑成12位切成2个6位,对应2个字符,后面补2个等号。剩2个字节16位,补0凑18位切成3个6位,对应3个字符,后面补1个等号。

所以看到Base64末尾一个等号,说明原始数据模3余2;两个等号说明模3余1;没等号说明正好整除。等号本身不携带数据,只是占位让长度凑成4的倍数,方便解码时还原原始长度。解码时把等号去掉,按位逆运算还原字节。

体积为什么变大三分之一

3字节变4字符,每字符还是占1字节,所以编码后体积是原来的4除3,约133%,也就是膨胀约三分之一。这是Base64的固有代价,换来的是二进制安全传输。所以Base64适合传小量数据或做信封,不适合传大文件,大文件压缩前先Base64更是浪费,因为压缩后随机性更强Base64几乎帮不上忙。

变体和坑

标准Base64字符表里加号和斜杠在URL里是特殊字符,加号会被解析成空格,斜杠是路径分隔符,所以URL和文件名场景要用URL安全的变体,把加号换成连字符,斜杠换成下划线,等号通常去掉。这就是URL Safe Base64。前端传参、生成文件名时一定确认用的是哪个变体,不然编码出来塞进URL会出错。

另一个坑是换行。MIME规范要求每76字符加一个换行,老邮件系统需要。但很多现代场景不换行,混了会解码失败。编码解码两端要对齐是否加换行。

还有Base64不是加密。它完全可逆、不带密钥,任何人都能解,只是换个表示方式。拿Base64当加密用是常见错误,密码、token裸Base64等于明文存。

常见问题

【Base64能压缩数据吗?】不能,反而膨胀约三分之一。它解决的是传输兼容不是体积。要压缩先用gzip等算法,别指望Base64。

【为什么有的Base64没有等号?】可能是URL Safe变体去掉了等号,也可能数据长度正好是3的倍数。解码时大多数库能容错,但严格场景要补齐等号再解。

【Base64比十六进制编码省多少?】十六进制每字节变2字符,膨胀一倍;Base64每3字节变4字符,膨胀三分之一。所以Base64比十六进制省约25%空间,这是用64替代16换来的。

【Base64解码失败一般什么原因?】常见是字符表变体不对,URL Safe和标准混了;或者混入了换行、空格、不可见字符;或者数据被截断长度不是4的倍数。先去掉空白、补齐等号、确认字符表再试。

标签: Base64 编码 二进制 数据转换

抱歉,评论功能暂时关闭!