Conversion de NSData en base64
comment convertir NSData
base64
. J'ai NSData
et que vous voulez convertir dans base64
comment puis-je faire cela?
7 réponses
EDIT
à partir de OS X 10.9 / iOS 7, ceci est intégré dans les cadres.
Voir -[NSData base64EncodedDataWithOptions:]
avant iOS7 / OS X 10.9:
Matt Gallagher a écrit un article sur ce même sujet. En bas, il donne un lien vers son code embeddable pour iPhone.
sur le mac vous pouvez utiliser la bibliothèque OpenSSL, sur l'iPhone il écrit son propre impl.
//from: http://cocoadev.com/BaseSixtyFour
+ (NSString*)base64forData:(NSData*)theData {
const uint8_t* input = (const uint8_t*)[theData bytes];
NSInteger length = [theData length];
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;
NSInteger i;
for (i=0; i < length; i += 3) {
NSInteger value = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
NSInteger theIndex = (i / 3) * 4;
output[theIndex + 0] = table[(value >> 18) & 0x3F];
output[theIndex + 1] = table[(value >> 12) & 0x3F];
output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
}
return [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
}
-[NSData base64EncodedStringWithOptions:]
-[NSData initWithBase64EncodedString:options:]
-[NSData initWithBase64EncodedData:options:]
-[NSData base64EncodedDataWithOptions:]
devrait éviter d'avoir à rouler votre propre méthode de catégorie
Super facile "drop-in" bibliothèque de Google code ici.
il suffit d'utiliser +rfc4648Base64StringEncoding
pour obtenir une instance, utilisez le encode
/decode
fonctions.
C'est une belle chose. (N'oubliez pas de récupérer le fichier d'en-tête et le GTMDefines.h
en-tête à partir de la racine.)
ce n'est pas facile. Comme dans Il n'y a pas de support construit en c ou obj-C. Voici ce que je fais (qui est en gros d'avoir le CL le faire pour moi):
- (NSString *)_base64Encoding:(NSString *) str
{
NSTask *task = [[[NSTask alloc] init] autorelease];
NSPipe *inPipe = [NSPipe pipe], *outPipe = [NSPipe pipe];
NSFileHandle *inHandle = [inPipe fileHandleForWriting], *outHandle = [outPipe fileHandleForReading];
NSData *outData = nil;
[task setLaunchPath:@"/usr/bin/openssl"];
[task setArguments:[NSArray arrayWithObjects:@"base64", @"-e", nil]];
[task setStandardInput:inPipe];
[task setStandardOutput:outPipe];
[task setStandardError:outPipe];
[task launch];
[inHandle writeData:[str dataUsingEncoding: NSASCIIStringEncoding]];
[inHandle closeFile];
[task waitUntilExit];
outData = [outHandle readDataToEndOfFile];
if (outData)
{
NSString *base64 = [[[NSString alloc] initWithData:outData encoding:NSUTF8StringEncoding] autorelease];
if (base64)
return base64;
}
return nil;
}
Et vous l'utilisez comme ceci:
NSString *b64str = [strToConvert _base64Encoding:strToConvert];
Et ce n'est pas mon code, je l'ai trouvé ici: http://www.cocoadev.com/index.pl?BaseSixtyFour et il fonctionne très bien. Vous pouvez toujours transformer cela en une méthode + ().
Oh, et pour obtenir votre NSData à un NSString pour cette méthode:
NSString *str = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
iOS a toujours inclus le support intégré pour l'encodage et le décodage de base64. Si vous regardez resolv.h
vous devriez voir les deux fonctions b64_ntop
et b64_pton
. Le Carré SocketRocket bibliothèque fournit un exemple raisonnable de la façon d'utiliser ces fonctions de l'objectif-C.
ces fonctions sont assez bien testées et fiables - contrairement à la plupart des implémentations que vous pouvez trouver dans des affichages aléatoires sur internet.
N'oubliez pas de lien contre libresolv.dylib
.
Si vous lien contre le SDK iOS 7, vous pouvez utiliser les nouvelles méthodes initWithBase64Encoding:
et base64EncodedDataWithOptions:
. Ceux-ci existent dans les versions précédentes, mais étaient privés. Donc, si vous vous liez avec le SDK 6, Vous pouvez entrer dans un comportement non défini. Ce serait un exemple de la façon d'utiliser ceci seulement lors de la liaison contre le 7 SDK:
#ifndef __IPHONE_7_0
// oh no! you are using something unsupported!
// Call and implementation that uses b64_pton here
#else
data = [[NSData alloc] initWithBase64Encoding:string];
#endif
j'ai modifié le code ci-dessus pour répondre à mes besoins, en construisant un post HTTP. J'ai pu sauter L'étape NSString, et inclure des sauts de ligne dans le code BASE64, qu'au moins un serveur web a trouvé plus acceptable:
#define LINE_SIZE 76
//originally from: http://www.cocoadev.com/index.pl?BaseSixtyFour
// via joshrl on stockoverflow
- (void) appendBase64Of: (NSData *)inData to:(NSMutableData *)outData {
const uint8_t* input = (const uint8_t*)[inData bytes];
NSInteger length = [inData length];
static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
uint8_t buf[LINE_SIZE + 4 + 2];
size_t n = 0;
NSInteger i;
for (i=0; i < length; i += 3) {
NSInteger value = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
value <<= 8;
if (j < length) {
value |= (0xFF & input[j]);
}
}
buf[n + 0] = table[(value >> 18) & 0x3F];
buf[n + 1] = table[(value >> 12) & 0x3F];
buf[n + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
buf[n + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
n += 4;
if (n + 2 >= LINE_SIZE) {
buf[n++] = '\r';
buf[n++] = '\n';
[outData appendBytes:buf length:n];
n = 0;
}
}
if (n > 0) {
buf[n++] = '\r';
buf[n++] = '\n';
[outData appendBytes:buf length:n];
}
return;
}