目录
什么是Base64
百度百科中对Base64有一个很好的解释:“Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法”。
什么是“可打印字符”呢?在ASCII码中规定,0~31、127这33个字符属于控制字符,32~126这95个字符属于可打印字符,也就是说网络传输只能传输这95个字符,不在这个范围内的字符无法传输。那么该怎么才能传输其他字符呢?其中一种方式就是使用Base64。
Base64,就是使用64个可打印字符来表示二进制数据的方法。Base64的索引与对应字符的关系如下表所示:
也就是说,如果将索引转换为对应的二进制数据的话需要至多6个Bit。然而ASCII码需要8个Bit来表示,那么怎么使用6个Bit来表示8个Bit的数据呢?6个Bit当然不能存储8个Bit的数据,但是4*6个Bit可以存储3*8个Bit的数据啊!如下表所示:
可以看到“Son”通过Base64编码转换成了“U29u”。这是刚刚好的情况,3个ASCII字符刚好转换成对应的4个Base64字符。但是,当需要转换的字符数不是3的倍数的情况下该怎么办呢?Base64规定,当需要转换的字符不是3的倍数时,一律采用补0的方式凑足3的倍数,具体如下表所示:
总结:
第一步:将二进制数据以每24Bit划分为一组,最后一组不足24Bit位的补0。
第二步:将24Bit的数据已每6Bit一组划分为4组,每组6Bit,这6Bit正好对应64个数。
第三步:参照对照表,64个数对应64个可见字符。000000 用 = 代替。
应用场景
场景一:
Base64一般用于在HTTP协议下传输二进制数据,由于HTTP协议是文本协议,所以在HTTP协议下传输二进制数据需要将二进制数据转换为字符数据。然而直接转换是不行的,因为网络传输只能传输可打印字符。其中一种方式就是使用Base64。比如上传图片时,可将图片转为二进制数据,然后转为base64可见字符,通过文本的形式上送后台,后台拿到Base64字符串后再转为二进制数据转为图片进行存储。
场景二:
在于后台通讯时,数据往往要加密,那么加密的数据如何来传输,此时可以将加密的数据转为Base64用于网络传输。
OC代码实现
普通字符串转为Base64字符串(本质是对二进制数据的编码)
+ (NSString *)base64FromString:(NSString*) aString{
/**
对于IOS7之后在NSData通过Base64转化为NSString时,有一个枚举参数:NSDataBase64EncodingOptions有四个值,在将其转化为NSString时,对其进行了处理:
NSDataBase64Encoding64CharacterLineLength
其作用是将生成的Base64字符串按照64个字符长度进行等分换行。每行64个字符,最后有个空行
d29tZW5kb3V5b3V5aWdlamlhbWluZ3ppamlhb3pob25nZ3VvamluZ3NleWVidWN1
b2RhamlhaGFvaGFvZGVzaGVuZ2h1b3dvbWVuZG91eW91eWlnZWppYW1pbmd6aWpp
YW96aG9uZ2d1b2ppbmdzZXllYnVjdW9kYWppYWhhb2hhb2Rlc2hlbmdodW8=
NSDataBase64Encoding76CharacterLineLength
其作用是将生成的Base64字符串按照76个字符长度进行等分换行。每行76个字符,最后有个空行
d29tZW5kb3V5b3V5aWdlamlhbWluZ3ppamlhb3pob25nZ3VvamluZ3NleWVidWN1b2RhamlhaGFv
aGFvZGVzaGVuZ2h1b3dvbWVuZG91eW91eWlnZWppYW1pbmd6aWppYW96aG9uZ2d1b2ppbmdzZXll
YnVjdW9kYWppYWhhb2hhb2Rlc2hlbmdodW8=
NSDataBase64EncodingEndLineWithCarriageReturn
其作用是将生成的Base64字符串以回车结束。最后有个空行
d29tZW5kb3V5b3V5aWdlamlhbWluZ3ppamlhb3pob25nZ3VvamluZ3NleWVidWN1b2RhamlhaGFv
aGFvZGVzaGVuZ2h1b3dvbWVuZG91eW91eWlnZWppYW1pbmd6aWppYW96aG9uZ2d1b2ppbmdzZXll
YnVjdW9kYWppYWhhb2hhb2Rlc2hlbmdodW8=
NSDataBase64EncodingEndLineWithLineFeed
其作用是将生成的Base64字符串以换行结束。格式如下,最后有个空行
d29tZW5kb3V5b3V5aWdlamlhbWluZ3ppamlhb3pob25nZ3VvamluZ3NleWVidWN1b2RhamlhaGFv
aGFvZGVzaGVuZ2h1b3dvbWVuZG91eW91eWlnZWppYW1pbmd6aWppYW96aG9uZ2d1b2ppbmdzZXll
YnVjdW9kYWppYWhhb2hhb2Rlc2hlbmdodW8=
*/
//字符串转为NSData
NSData * decodeData = [aString dataUsingEncoding:NSUTF8StringEncoding];
//编码 0为默认值
//NSDataBase64EncodingEndLineWithCarriageReturn 或者
//NSDataBase64EncodingEndLineWithLineFeed
NSData * encodeData = [decodeData base64EncodedDataWithOptions:0];
//转为字符串
NSString * encodeStr = [[NSString alloc] initWithData:encodeData encoding:NSUTF8StringEncoding];
return encodeStr;
}
Base64字符串转为普通字符串(本质是对二进制数据的解码)
+ (NSString *)decodeFromString:(NSString *)aString{
//NSDataBase64DecodingIgnoreUnknownCharacters 忽略非Base64字符 如:换行符
NSData * data = [[NSData alloc] initWithBase64EncodedString:aString options:NSDataBase64DecodingIgnoreUnknownCharacters];
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
图片转为Base64字符串用于传输
-(NSString*)base64StringFromImage:(UIImage*)image{
NSData * data = UIImageJPEGRepresentation(image, 1.0);
if (!data) {
data = UIImagePNGRepresentation(image);
}
return data?[data base64EncodedStringWithOptions:0]:nil;
}
Base64字符串转为图片
-(UIImage*)imageFromBase64String:(NSString*)base64String{
NSData * data = [[NSData alloc] initWithBase64EncodedString:base64String options:NSDataBase64DecodingIgnoreUnknownCharacters];
return data?[[UIImage alloc] initWithData:data]:nil;
}
PS:Base64只是一种编码方式,并不是一种加密方式。
行者常至,为者常成!