Created
September 26, 2012 11:42
-
-
Save leovandriel/3787536 to your computer and use it in GitHub Desktop.
Objective-C methods for Base64 conversion between NSString and NSData
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Objective-C methods for Base64 conversion between NSString and NSData. | |
// Note: these do not support trailing '=' characters. | |
// License: Public Domain | |
// Author: Leonard van Driel, 2012 | |
static unsigned char toBase64String[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; | |
static unsigned char toBase64Data[256] = { | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, | |
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, | |
64, 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, 12, 13, 14, | |
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, | |
64, 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, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, | |
}; | |
@implementation NSString (Base64) | |
- (NSData *)base64Data | |
{ | |
// filter empty | |
NSUInteger length = self.length; | |
if (!length) { | |
return [NSData data]; | |
} | |
// set up data | |
NSUInteger resultLength = (3 * length + 1) / 4; | |
unsigned char *bytes = calloc(resultLength, sizeof(unsigned char)); | |
// set up loop | |
const char *input = [self cStringUsingEncoding:NSASCIIStringEncoding]; | |
unsigned char *output = bytes; | |
// convert body | |
for (const char *end = input + (length + 1); input < end; input++) { | |
*(output++) = (toBase64Data[*input] << 2) | ((toBase64Data[*(++input)] & 0x30) >> 4); | |
*(output++) = ((toBase64Data[*input] & 0x0F) << 4) | ((toBase64Data[*(++input)] & 0x3C) >> 2); | |
*(output++) = ((toBase64Data[*input] & 0x03) << 6) | (toBase64Data[*(++input)] & 0x3F) ; | |
} | |
// convert tail | |
NSUInteger remain = length % 4; | |
if (remain) { | |
if (remain == 1) { | |
*(output++) = (toBase64Data[*input] << 2); | |
} else if (remain == 2) { | |
*(output++) = (toBase64Data[*input] << 2) | ((toBase64Data[*(++input)] & 0x30) >> 4); | |
*(output++) = ((toBase64Data[*input] & 0x0F) << 4); | |
} else { | |
*(output++) = (toBase64Data[*input] << 2) | ((toBase64Data[*(++input)] & 0x30) >> 4); | |
*(output++) = ((toBase64Data[*input] & 0x0F) << 4) | ((toBase64Data[*(++input)] & 0x3C) >> 2); | |
*(output++) = ((toBase64Data[*input] & 0x03) << 6); | |
} | |
} | |
// init string | |
NSData *result = [[NSData alloc] initWithBytesNoCopy:bytes length:resultLength freeWhenDone:YES]; | |
return result; | |
} | |
@end | |
@implementation NSData (Base64) | |
- (NSString *)base64String | |
{ | |
// filter empty | |
NSUInteger length = self.length; | |
if (!length) { | |
return [NSString string]; | |
} | |
// set up string | |
NSUInteger resultLength = (4 * length + 2) / 3; | |
char *chars = calloc(resultLength, sizeof(char)); | |
// set up loop | |
const unsigned char *input = self.bytes; | |
char *output = chars; | |
// convert body | |
for (const unsigned char *end = input + length; input + 2 < end; input++) { | |
*(output++) = toBase64String[ * input >> 2 ]; | |
*(output++) = toBase64String[((*input & 0x03) << 4) | (*(++input) >> 4)]; | |
*(output++) = toBase64String[((*input & 0x0F) << 2) | (*(++input) >> 6)]; | |
*(output++) = toBase64String[ *input & 0x3F ]; | |
} | |
// convert tail | |
NSUInteger remain = length % 3; | |
if (remain) { | |
*(output++) = toBase64String[*input >> 2]; | |
if (remain == 1) { | |
*(output++) = toBase64String[((*input & 0x03) << 4)]; | |
} else { | |
*(output++) = toBase64String[((*input & 0x03) << 4) | (*(++input) >> 4)]; | |
*(output++) = toBase64String[((*input & 0x0F) << 2)]; | |
} | |
} | |
// init string | |
NSString *result = [[NSString alloc] initWithBytesNoCopy:chars length:resultLength encoding:NSASCIIStringEncoding freeWhenDone:YES]; | |
return result; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment