// // Base64.m // BellFramework // // Created by 罗兴志 on 2017/5/4. // Copyright © 2017年 罗兴志. All rights reserved. // #import "Base64.h" @interface Base64() +(int)char2Int:(char)c; @end @implementation Base64 static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +(NSString *)encode:(NSData *)data { if (data.length == 0) return nil; char *characters = malloc(data.length * 3 / 2); if (characters == NULL) return nil; int end = data.length - 3; int index = 0; int charCount = 0; int n = 0; while (index <= end) { int d = (((int)(((char *)[data bytes])[index]) & 0x0ff) << 16) | (((int)(((char *)[data bytes])[index + 1]) & 0x0ff) << 8) | ((int)(((char *)[data bytes])[index + 2]) & 0x0ff); characters[charCount++] = encodingTable[(d >> 18) & 63]; characters[charCount++] = encodingTable[(d >> 12) & 63]; characters[charCount++] = encodingTable[(d >> 6) & 63]; characters[charCount++] = encodingTable[d & 63]; index += 3; if(n++ >= 14) { n = 0; characters[charCount++] = ' '; } } if(index == data.length - 2) { int d = (((int)(((char *)[data bytes])[index]) & 0x0ff) << 16) | (((int)(((char *)[data bytes])[index + 1]) & 255) << 8); characters[charCount++] = encodingTable[(d >> 18) & 63]; characters[charCount++] = encodingTable[(d >> 12) & 63]; characters[charCount++] = encodingTable[(d >> 6) & 63]; characters[charCount++] = '='; } else if(index == data.length - 1) { int d = ((int)(((char *)[data bytes])[index]) & 0x0ff) << 16; characters[charCount++] = encodingTable[(d >> 18) & 63]; characters[charCount++] = encodingTable[(d >> 12) & 63]; characters[charCount++] = '='; characters[charCount++] = '='; } NSString * rtnStr = [[NSString alloc] initWithBytesNoCopy:characters length:charCount encoding:NSUTF8StringEncoding freeWhenDone:YES]; return rtnStr; } +(NSData *)decode:(NSString *)data { if(data == nil || data.length <= 0) { return nil; } NSMutableData *rtnData = [[NSMutableData alloc]init]; int slen = data.length; int index = 0; while (true) { while (index < slen && [data characterAtIndex:index] <= ' ') { index++; } if (index >= slen || index + 3 >= slen) { break; } int byte = ([self char2Int:[data characterAtIndex:index]] << 18) + ([self char2Int:[data characterAtIndex:index + 1]] << 12) + ([self char2Int:[data characterAtIndex:index + 2]] << 6) + [self char2Int:[data characterAtIndex:index + 3]]; Byte temp1 = (byte >> 16) & 255; [rtnData appendBytes:&temp1 length:1]; if([data characterAtIndex:index + 2] == '=') { break; } Byte temp2 = (byte >> 8) & 255; [rtnData appendBytes:&temp2 length:1]; if([data characterAtIndex:index + 3] == '=') { break; } Byte temp3 = byte & 255; [rtnData appendBytes:&temp3 length:1]; index += 4; } return rtnData; } +(int)char2Int:(char)c { if (c >= 'A' && c <= 'Z') { return c - 65; } else if (c >= 'a' && c <= 'z') { return c - 97 + 26; } else if (c >= '0' && c <= '9') { return c - 48 + 26 + 26; } else { switch(c) { case '+': return 62; case '/': return 63; case '=': return 0; default: return -1; } } } @end