一、Base64簡介
Base64是網(wǎng)絡(luò)上最常見的用于傳輸8Bit字節(jié)代碼的編碼方式之一。Base64編碼可用于在HTTP環(huán)境下傳遞較長的標識信息。例如,在Java Persistence系統(tǒng)Hibernate中,就采用了Base64來將一個較長的唯一標識符(一般為128-bit的UUID)編碼為一個字符串,用作HTTP表單和HTTP GET URL中的參數(shù)。在其他應(yīng)用程序中,也常常需要把二進制數(shù)據(jù)編碼為適合放在URL(包括隱藏表單域)中的形式。此時,采用Base64編碼具有不可讀性,即所編碼的數(shù)據(jù)不會被人用肉眼所直接看到。做過XMPP開發(fā)的朋友可能使用過Base64將圖片編碼后再傳輸。另外迅雷的“專用地址”也是用Base64"加密"的,其過程是在地址的前后分別添加AA和ZZ,然后對新的字符串進行Base64編碼。
需要說明的是Base64 可以對任意的文件進行加密,但是Base64 過程是可逆的. 可以反向解密。所以,嚴格地講Base64只是一種編碼方式,并非加密算法。另外Base64將原來8個bit為一個字節(jié)的數(shù)據(jù),6個bit為一個單位處理,會導(dǎo)致數(shù)據(jù)量會增大1/3[(8-6)/6]。
二、算法描述
描述出處
轉(zhuǎn)碼過程例子:
3*8=4*6
內(nèi)存1個字符占8位
轉(zhuǎn)前: s 1 3
先轉(zhuǎn)成ascii:對應(yīng) 115 49 51
2進制: 01110011 00110001 00110011
6個一組(4組) 011100110011000100110011
然后才有后面的 011100 110011 000100 110011
然后計算機是8位8位的存數(shù) 6不夠,自動就補兩個高位0了
所有有了 高位補0
科學(xué)計算器輸入 00011100 00110011 00000100 00110011
得到 28 51 4 51
查對下照表 c z E z
三、算法實現(xiàn)
@implementation CATSecurity
#pragma mark --
#pragma mark -- Base64
static const char base64EncodingTable[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const short base64DecodingTable[256] = {
-2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -1, -1, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2,
-2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2,
-2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
-2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
};
/**
* get data's base64 encoded string
*
* @param data source data
*
* @return base64 encoded string
*/
+(NSString *)base64EncodedStringWithData:(NSData *)data{
NSUInteger length = data.length;
if (length == 0)
return @"";
NSUInteger out_length = ((length + 2) / 3) * 4;
uint8_t *output = malloc(((out_length + 2) / 3) * 4);
if (output == NULL)
return nil;
const char *input = data.bytes;
NSInteger i, value;
for (i = 0; i < length; i += 3) {
value = 0;
for (NSInteger j = i; j < i + 3; j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger index = (i / 3) * 4;
output[index + 0] = base64EncodingTable[(value >> 18) & 0x3F];
output[index + 1] = base64EncodingTable[(value >> 12) & 0x3F];
output[index + 2] = ((i + 1) < length)
? base64EncodingTable[(value >> 6) & 0x3F]
: '=';
output[index + 3] = ((i + 2) < length)
? base64EncodingTable[(value >> 0) & 0x3F]
: '=';
}
NSString *base64 = [[NSString alloc] initWithBytes:output length:out_length encoding:NSASCIIStringEncoding];
free(output);
return base64;
}
/**
* get source data from base64 encoded string
*
* @param base64EncodedString base64 encoded string
*
* @return source data
*/
+(NSData *)dataWithBase64EncodedString:(NSString *)base64EncodedString{
NSInteger length = base64EncodedString.length;
const char *string = [base64EncodedString cStringUsingEncoding:NSASCIIStringEncoding];
if (string == NULL)
return nil;
while (length > 0 && string[length - 1] == '=')
length--;
NSInteger outputLength = length * 3 / 4;
NSMutableData *data = [NSMutableData dataWithLength:outputLength];
if (data == nil)
return nil;
if (length == 0)
return data;
uint8_t *output = data.mutableBytes;
NSInteger inputPoint = 0;
NSInteger outputPoint = 0;
while (inputPoint < length) {
char i0 = string[inputPoint++];
char i1 = string[inputPoint++];
char i2 = inputPoint < length ? string[inputPoint++] : 'A';
char i3 = inputPoint < length ? string[inputPoint++] : 'A';
output[outputPoint++] = (base64DecodingTable[i0] << 2)
| (base64DecodingTable[i1] >> 4);
if (outputPoint < outputLength) {
output[outputPoint++] = ((base64DecodingTable[i1] & 0xf) << 4)
| (base64DecodingTable[i2] >> 2);
}
if (outputPoint < outputLength) {
output[outputPoint++] = ((base64DecodingTable[i2] & 0x3) << 6)
| base64DecodingTable[i3];
}
}
return data;
}
/**
* get str's base64 encoded string
*
* @param str source string
*
* @return base64 encoded string
*/
+(NSString *)base64EncodedStringWithString:(NSString *)str{
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
return [self base64EncodedStringWithData:data];
}
/**
* get source string from base64 encoded string
*
* @param base64EncodedString base64 encoded string
*
* @return source string
*/
+ (NSString *)stringWithBase64EncodedString:(NSString *)base64EncodedString{
NSData *data = [self dataWithBase64EncodedString:base64EncodedString];
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
@end
最后附上工程地址。