本文共 8332 字,大约阅读时间需要 27 分钟。
在使用文本编辑器打开二进制文件时,其二进制数据并不是全部可见的字符,所以会出现乱码。
为了避免这种情况,使用 Base64 编码的方式,将二进制数据编码为可见字符。注意 Base64 编码是一种编码方法并不是加密方法。
将一段二进制数据进行 Base64 编码,步骤如下:
将一段经过 Base64 编码得到的字符串解码为原二进制数据,步骤如下:
iOS 官方接口 NSData 的分类 NSDataBase64Encoding 中提供了 Base64 的相关方法,如下:
@interface NSData (NSDataBase64Encoding)/* 使用经过 Base64 编码后的字符串,初始化一个 NSData 类实例,这里就是将 Base64 编码后的字符串进行了解码,得到原始的二进制数据*/- (instancetype)initWithBase64EncodedString:(NSString *)base64String options:(NSDataBase64DecodingOptions)options NS_AVAILABLE(10_9, 7_0);/* 使用自身的二进制数据进行 Base64 编码,最后返回编码后的字符串*/- (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)options NS_AVAILABLE(10_9, 7_0);/* 使用经过 Base64 编码后得到的二进制数据,初始化一个 NSData 类实例,这里就是将 Base64 编码后的二进制数据进行了解码,得到原始的二进制数据*/- (instancetype)initWithBase64EncodedData:(NSData *)base64Data options:(NSDataBase64DecodingOptions)options NS_AVAILABLE(10_9, 7_0);/*使用自身的二进制数据进行 Base64 编码,最后返回编码后的二进制数据*/- (NSData *)base64EncodedDataWithOptions:(NSDataBase64EncodingOptions)options NS_AVAILABLE(10_9, 7_0);@end上面4种方法,可看做两组方法,分别进行了编码和解码操作,只是前两个方法,编码的结果和解码的入参都是字符串,后两种是二进制数据。
除了调用 iOS 提供的方法,还可以自己实现 Base64 编码及解码,如下:
#import@interface Base64 : NSObject/** 对提供的二进制数据进行Base64编码 @param data 待编码的二进制数据 */+ (NSString *)base64Encode:(NSData *)data;/** 将经过Base64编码的字符串解码为原二进制数据 @param base64String 待解码的Base64字符串 */+ (NSData *)base64Decode:(NSString *)base64String;@end
#import "Base64.h"@implementation Base64#pragma mark - base64 编码+ (NSString *)base64Encode:(NSData *)data{ NSMutableData *base64 = [NSMutableData new]; NSRange range = NSMakeRange(0, 3); unsigned char buffer[3] = { 0}; unsigned char base[4] = { 0}; //三的整数倍数据 double index = data.length / 3 * 3; while (range.location + range.length <= index) { [data getBytes:buffer range:range]; //第一个 6 bit base[0] = base64_table[buffer[0] >> 2]; //第二个 6 bit base[1] = base64_table[(buffer[0] & 0b11) << 4 | (buffer[1] >> 4)]; //第三个 6 bit base[2] = base64_table[(buffer[1] & 0b1111) << 2 | (buffer[2] >> 6)]; //第四个 6 bit base[3] = base64_table[buffer[2] & 0b111111]; [base64 appendBytes:base length:4]; range.location +=range.length; } //处理最后一个字节或两个字节数据 if (data.length%3 == 1) { [data getBytes:buffer range:NSMakeRange(index, 1)]; //第一个 6 bit base[0] = base64_table[buffer[0] >> 2]; //第二个 6 bit base[1] = base64_table[(buffer[0] & 0b11) << 4 | 0]; base[2] = '='; base[3] = '='; [base64 appendBytes:base length:4]; }else if (data.length%3 == 2){ [data getBytes:buffer range:NSMakeRange(index, 2)]; //第一个 6 bit base[0] = base64_table[buffer[0] >> 2]; //第二个 6 bit base[1] = base64_table[(buffer[0] & 0b11) << 4 | (buffer[1] >> 4)]; //第三个 6 bit base[2] = base64_table[(buffer[1] & 0b1111) << 2 | 0]; base[3] = '='; [base64 appendBytes:base length:4]; } return [[NSString alloc] initWithData:base64 encoding:NSUTF8StringEncoding];}#pragma mark - base64 解码+ (NSData *)base64Decode:(NSString *)base64String{ NSData *data = [base64String dataUsingEncoding:NSUTF8StringEncoding]; if (data.length % 4) { NSLog(@"Base64 decode error : %@",[NSError errorWithDomain:@"The source data is not base64 code ." code:0 userInfo:nil]); return nil; } NSMutableData *srcData = [NSMutableData new]; unsigned char buffer[3] = { 0}; unsigned char base[4] = { 0}; int32_t temp = 0; NSRange range = NSMakeRange(0, 4); while (range.location + range.length < data.length) { [data getBytes:base range:range]; temp |= deBase64_table[base[0]]; temp <<= 6; temp |= deBase64_table[base[1]]; temp <<= 6; temp |= deBase64_table[base[2]]; temp <<= 6; temp |= deBase64_table[base[3]]; buffer[0] = (temp & 0xFF0000) >> 16; buffer[1] = (temp & 0x00FF00) >> 8; buffer[2] = (temp & 0x0000FF); [srcData appendBytes:buffer length:3]; temp = 0; range.location += 4; } [data getBytes:base range:range]; if (base[2] == '=') { base[2] = 0; base[3] = 0; temp |= deBase64_table[base[0]]; temp <<= 6; temp |= deBase64_table[base[1]]; buffer[0] = temp >> 4; [srcData appendBytes:buffer length:1]; }else if (base[3] == '='){ base[3] = 0; temp |= deBase64_table[base[0]]; temp <<= 6; temp |= deBase64_table[base[1]]; temp <<= 6; temp |= deBase64_table[base[2]]; buffer[0] = (temp >> 2 & 0xFF00) >> 8; buffer[1] = (temp >> 2 & 0x00FF); [srcData appendBytes:buffer length:2]; }else { temp |= deBase64_table[base[0]]; temp <<= 6; temp |= deBase64_table[base[1]]; temp <<= 6; temp |= deBase64_table[base[2]]; temp <<= 6; temp |= deBase64_table[base[3]]; buffer[0] = (temp & 0xFF0000) >> 16; buffer[1] = (temp & 0x00FF00) >> 8; buffer[2] = (temp & 0x0000FF); [srcData appendBytes:buffer length:3]; } return [NSData dataWithData:srcData];}static const char base64_table[64] ={ 'A','B','C','D','E','F','G','H', 'I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X', 'Y','Z','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n', 'o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3', '4','5','6','7','8','9','+','/'};static const char deBase64_table[] ={ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x00,0x00,0x3F, 0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E, 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x00,0x00,0x00,0x00,0x00, 0x00,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28, 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};@end
测试代码如下:
- (IBAction)btnClickedOfBase64:(UIButton *)sender { NSString *test = @"this is a test string !"; NSLog(@"origin string : %@",test); NSData *data = [test dataUsingEncoding:NSUTF8StringEncoding]; NSLog(@"origin data : %@",data); //编码 NSString *baseString = [Base64 base64Encode:data]; NSLog(@"baseString : %@",baseString); NSString *baseString1 = [data base64EncodedStringWithOptions:0]; NSLog(@"baseString1 : %@",baseString1); //解码 NSData *decodeData = [Base64 base64Decode:baseString]; NSLog(@"decodeData : %@",decodeData); NSData *decodeData1 = [[NSData alloc]initWithBase64EncodedString:baseString options:0]; NSLog(@"decodeData1 : %@",decodeData1); //编码 NSData *base64Data = [data base64EncodedDataWithOptions:0]; NSLog(@"base64Data : %@",base64Data); //解码 NSData *base64DataDecode = [[NSData alloc]initWithBase64EncodedData:base64Data options:0]; NSLog(@"base64DataDecode : %@",base64DataDecode); NSString *decodeString = [[NSString alloc]initWithData:base64DataDecode encoding:NSUTF8StringEncoding]; NSLog(@"decodeString : %@",decodeString);}
转载地址:http://qtdws.baihongyu.com/