一、介绍
Base64编码是一种数据编码方式,目的是让数据符合传输协议的要求。能够将任何二进制数据,转换成只有64 +1(“=”等号)个字符组成的文本文件。
提示:Base64不是加密算法,只是一种编码算法,对数据内容进行编码不以明文来传输。
标准Base64编码使用的64个字符:
二、作用
早期的传输协议,如邮件传输SMTP协议,只能传输ASCII编码中可打印字符,导致原本8bit字节码(0-255)超出了可用范围。所以Base64将原本ASCII码的控制字符甚至是ASCII编码之外的字符都转换成可打印的6bit字符。
提示:ASCII编码的范围是0-127,其中0-31和127位共33个字符属于控制字符,剩下的32-126属于可打印字符。
三、原理
编码过程:
1、按字符串长度,以每3个8bit的字符为一组
2、对每组获取每个字符的ASCII编码(去ASCII编码表找每个字符的码位)
3、将ASCII编码转换成8bit的二进制,得到一组3*8=24bit的字节
4、再将这24bit划分为4个6bit的字节,并在每个6bit的字节前面都填两个高位0,得到4个8bit的字节
5、将这4个8bit的字节转换成10进制,对照Base64编码表 (下表),得到对应编码后的字符。
注意:
- 要求被Base64编码字符是可以用8bit来表示,也就是一个字节来表示的,所以须在ASCII编码范围内,\u0000-\u00ff,中文不行,中文需要两个字节来表示。
- 如果被编码字符长度不是3的倍数的时候,则都用0代替,对应的输出字符为=。
示例:对 Hello! 进行Base64编码,按照ASCII表,其转换过程如下图所示:
Hello! 的Base64编码结果为 SGVsbG8h 。
原始字符串长度为6个字符,编码后长度为8个字符,每3个原始字符经Base64编码成4个字符,编码前后长度比4/3。
这个长度比很重要 。比原始字符串长度短,则需要使用更大的编码字符集,长度比越大,则需要传输越多的字符,传输时间越长。
Base64应用广泛的原因是在字符集大小与长度比之间取得一个较好的平衡,适用于各种场景。
注意:Base64编码是每3个原始字符编码成4个字符,如果原始字符串长度不能被3整除,那怎么办?使用0值来补充原始字符串。
示例:对 Hello!! 进行Base64编码:
注:图中蓝色背景的二进制0值是额外补充的。
Hello!! 的Base64编码的结果为 SGVsbG8hIQAA 。
最后2个零值只是为了Base64编码而补充的,在原始字符中并没有对应的字符,那么Base64编码结果中的最后两个字符 AA 实际不带有效信息,所以需要特殊处理,以免解码错误。
标准Base64编码通常用 = 字符来替换最后的 A,即编码结果为 SGVsbG8hIQ==。
因为 = 字符并不在Base64编码索引表中,其意义在于结束符号,在Base64解码时遇到 = 时即可知道一个Base64编码字符串结束。
如果Base64编码字符串不会相互拼接再传输,那么最后的 = 可以省略,解码时如果发现Base64编码字符串长度不能被4整除,则先补充 = 字符,再解码即可。
解码是对编码的逆向操作,但注意一点:对于最后的两个 = 字符,转换成两个 A 字符,再转成对应的两个6比特二进制0值,接着转成原始字符之前,需要将最后的两个6比特二进制0值丢弃,因为它们实际上不携带有效信息。
四、代码
//.h
#import <Foundation/Foundation.h>
@interface NSString (Base64)
/**
* 转换为Base64编码
*/
- (NSString *)base64EncodedString;
/**
* 将Base64编码还原
*/
- (NSString *)base64DecodedString;
@end
//.m
- (NSString *)base64EncodedString;
{
NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
return [data base64EncodedStringWithOptions:0];
}
- (NSString *)base64DecodedString
{
NSData *data = [[NSData alloc]initWithBase64EncodedString:self options:0];
return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
}
五、UTF-8与Base64的区别
UTF-8是Unicode字符集的编码规则,用于网络传输。
Base64是用来支持某些只支持传输ASCII编码可打印字符的协议,将ASCII编码中的控制字符与ASCII之外的字符转换为ASCII可打印字符来用于传输。
参考链接
漫画:什么是 Base64 算法?
iOS开发探索-Base64编码
关于base64编码的原理及实现
ASCII码对照表