JHHK

欢迎来到我的个人网站
行者常至 为者常成

Base64

目录

什么是Base64

百度百科中对Base64有一个很好的解释:“Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法”。

什么是“可打印字符”呢?在ASCII码中规定,0~31、127这33个字符属于控制字符,32~126这95个字符属于可打印字符,也就是说网络传输只能传输这95个字符,不在这个范围内的字符无法传输。那么该怎么才能传输其他字符呢?其中一种方式就是使用Base64。

Base64,就是使用64个可打印字符来表示二进制数据的方法。Base64的索引与对应字符的关系如下表所示:

img

也就是说,如果将索引转换为对应的二进制数据的话需要至多6个Bit。然而ASCII码需要8个Bit来表示,那么怎么使用6个Bit来表示8个Bit的数据呢?6个Bit当然不能存储8个Bit的数据,但是4*6个Bit可以存储3*8个Bit的数据啊!如下表所示:

img

可以看到“Son”通过Base64编码转换成了“U29u”。这是刚刚好的情况,3个ASCII字符刚好转换成对应的4个Base64字符。但是,当需要转换的字符数不是3的倍数的情况下该怎么办呢?Base64规定,当需要转换的字符不是3的倍数时,一律采用补0的方式凑足3的倍数,具体如下表所示:

img

总结:

第一步:将二进制数据以每24Bit划分为一组,最后一组不足24Bit位的补0。

第二步:将24Bit的数据已每6Bit一组划分为4组,每组6Bit,这6Bit正好对应64个数。

第三步:参照对照表,64个数对应64个可见字符。000000 用 = 代替。

应用场景

场景一:

Base64一般用于在HTTP协议下传输二进制数据,由于HTTP协议是文本协议,所以在HTTP协议下传输二进制数据需要将二进制数据转换为字符数据。然而直接转换是不行的,因为网络传输只能传输可打印字符。其中一种方式就是使用Base64。比如上传图片时,可将图片转为二进制数据,然后转为base64可见字符,通过文本的形式上送后台,后台拿到Base64字符串后再转为二进制数据转为图片进行存储。

场景二:

在于后台通讯时,数据往往要加密,那么加密的数据如何来传输,此时可以将加密的数据转为Base64用于网络传输。

img

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只是一种编码方式,并不是一种加密方式。


行者常至,为者常成!





R
Valine - A simple comment system based on Leancloud.