Skip to content

Instantly share code, notes, and snippets.

@leovandriel
Created September 26, 2012 11:42
Show Gist options
  • Save leovandriel/3787536 to your computer and use it in GitHub Desktop.
Save leovandriel/3787536 to your computer and use it in GitHub Desktop.
Objective-C methods for Base64 conversion between NSString and NSData
// 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