base64String原理及方法
2016-05-13 14:18
211 查看
用ToBase64String方法可以在不丢失数据的情况下将字节数组转成字符串
在ToBase64String方法中,会对字节数组中的连续三字节进行一次编码,编码得的字符串长度为4位,而且得出来的4位的字符串里面的字符肯定是由大小写字母、数字(0~9)、+、/组成,例如有一个字节数组{212,36,25,23,45,65},ToBase64String方法会将这个数组分成2个数组,分别为{212,36,25}和{23,45,65},{212,36,25}计算出来的字符串是“1CQZ”,而{23,45,65} 是“Fy1B”,如果是{212,36,25,23},则先分成两个数组,{212,36,25}和{23},{212,36,25}已经计算过了,但{23}不足三字节,怎么办?{23}会转换成“Fw==”,所以{212,36,25}和{23,45,65},{212,36,25}转换出来的字符串是“1CQZFy1B”,{212,36,25,23}是“1CQZFw==”。
为什么会这样转换呢?
在ToBase64String中,利用了52个大小写字母,10个数字,“+”和“/”一共64个字符组成三个不同的矩阵,因为这三个矩阵比较大,不好放出来,所以你可以在附件中看到这在个矩阵的情况。当一个数组中只由1个字节组成时,在ToBase64String方法中只会用到第一个矩阵,当由2个字节组成时,在ToBase64String方法中会用到第一和第二个矩阵,当由3个字节组成时, ToBase64String方法中就会用全1、2、3这三个矩阵。
而在这三个矩阵中,是一阵扣一阵。例如要用到第三个矩阵,就要求从第一个矩阵计算出第二个矩阵的起码编码,根据字节的大小计算第二矩阵经过偏移量得出的编码,再由每二矩阵编码找到第三矩阵的偏移编码,找到第三矩阵编码后,最后由第一矩阵的纵码+第二矩阵纵码+第三矩阵纵码+第三矩阵横码=最后的转换字符串.
实现方法
nsstring*base64string(nsstring*string){
NSData *data = [NSDatadataWithBytes:[string
UTF8String]length:[string
lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
NSUInteger length = [datalength];
NSMutableData *mutableData = [NSMutableDatadataWithLength:((length +
2) /3) *
4];
uint8_t *input = (uint8_t *)[databytes];
uint8_t *output = (uint8_t *)[mutableDatamutableBytes];
for (NSUInteger i =0; i < length; i +=
3) {
NSUInteger value =0;
for (NSUInteger j = i; j < (i +3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
static
uint8_t const kAFBase64EncodingTable[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
NSUInteger idx = (i /3) *
4;
output[idx + 0] = kAFBase64EncodingTable[(value >>18) &
0x3F];
output[idx + 1] = kAFBase64EncodingTable[(value >>12) &
0x3F];
output[idx + 2] = (i +1) < length ? kAFBase64EncodingTable[(value >>6) &
0x3F] :'=';
output[idx + 3] = (i +2) < length ? kAFBase64EncodingTable[(value >>0) &
0x3F] :'=';
}
return [[NSStringalloc]
initWithData:mutableDataencoding:NSASCIIStringEncoding];
}
为甚么要转换成base64String?
采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
在ToBase64String方法中,会对字节数组中的连续三字节进行一次编码,编码得的字符串长度为4位,而且得出来的4位的字符串里面的字符肯定是由大小写字母、数字(0~9)、+、/组成,例如有一个字节数组{212,36,25,23,45,65},ToBase64String方法会将这个数组分成2个数组,分别为{212,36,25}和{23,45,65},{212,36,25}计算出来的字符串是“1CQZ”,而{23,45,65} 是“Fy1B”,如果是{212,36,25,23},则先分成两个数组,{212,36,25}和{23},{212,36,25}已经计算过了,但{23}不足三字节,怎么办?{23}会转换成“Fw==”,所以{212,36,25}和{23,45,65},{212,36,25}转换出来的字符串是“1CQZFy1B”,{212,36,25,23}是“1CQZFw==”。
为什么会这样转换呢?
在ToBase64String中,利用了52个大小写字母,10个数字,“+”和“/”一共64个字符组成三个不同的矩阵,因为这三个矩阵比较大,不好放出来,所以你可以在附件中看到这在个矩阵的情况。当一个数组中只由1个字节组成时,在ToBase64String方法中只会用到第一个矩阵,当由2个字节组成时,在ToBase64String方法中会用到第一和第二个矩阵,当由3个字节组成时, ToBase64String方法中就会用全1、2、3这三个矩阵。
而在这三个矩阵中,是一阵扣一阵。例如要用到第三个矩阵,就要求从第一个矩阵计算出第二个矩阵的起码编码,根据字节的大小计算第二矩阵经过偏移量得出的编码,再由每二矩阵编码找到第三矩阵的偏移编码,找到第三矩阵编码后,最后由第一矩阵的纵码+第二矩阵纵码+第三矩阵纵码+第三矩阵横码=最后的转换字符串.
实现方法
nsstring*base64string(nsstring*string){
NSData *data = [NSDatadataWithBytes:[string
UTF8String]length:[string
lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
NSUInteger length = [datalength];
NSMutableData *mutableData = [NSMutableDatadataWithLength:((length +
2) /3) *
4];
uint8_t *input = (uint8_t *)[databytes];
uint8_t *output = (uint8_t *)[mutableDatamutableBytes];
for (NSUInteger i =0; i < length; i +=
3) {
NSUInteger value =0;
for (NSUInteger j = i; j < (i +3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
static
uint8_t const kAFBase64EncodingTable[] ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
NSUInteger idx = (i /3) *
4;
output[idx + 0] = kAFBase64EncodingTable[(value >>18) &
0x3F];
output[idx + 1] = kAFBase64EncodingTable[(value >>12) &
0x3F];
output[idx + 2] = (i +1) < length ? kAFBase64EncodingTable[(value >>6) &
0x3F] :'=';
output[idx + 3] = (i +2) < length ? kAFBase64EncodingTable[(value >>0) &
0x3F] :'=';
}
return [[NSStringalloc]
initWithData:mutableDataencoding:NSASCIIStringEncoding];
}
为甚么要转换成base64String?
采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。
相关文章推荐
- redmine启动失败问题couldn't find HOME environment -- expanding
- ipsec配置strongswan.conf和ipsec.conf
- Servlet的生命周期及工作原理
- 计算文件大小
- PS简单制作一个动态的字体动画
- 技术的概念
- DIV设置最小高度
- CLR的执行模型
- android 系统提示对话框(AlertDialog)的使用
- Torch7深度学习教程(六)
- Dom4j解析xml格式的字符串【java】
- 商城购物车的实现设计思想
- Linux 新增一块硬盘,添加到已有逻辑卷
- linux常用命令
- 长程序启动脚本,关闭脚本,清理日志~
- Mac OS X搭建C#开发环境
- PopUpWindow
- http://www.tuicool.com/articles/vQRnum
- 【无人驾驶系列】光学雷达(LiDAR)在无人驾驶技术中的应用
- CSDN学院“跟着龙哥学JavaWeb”的笔记,请求中文参数的乱码处理