Conversion de NSData en base64

comment convertir NSDatabase64. J'ai NSData et que vous voulez convertir dans base64 comment puis-je faire cela?

36
demandé sur Girish 2010-02-04 07:46:51

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.

48
répondu Ken 2013-10-03 09:26:24
//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];
}
27
répondu joshrl 2013-07-05 22:02:58
NSData (NSDataBase64Encoding) avec des méthodes

-[NSData base64EncodedStringWithOptions:]
-[NSData initWithBase64EncodedString:options:]
-[NSData initWithBase64EncodedData:options:]
-[NSData base64EncodedDataWithOptions:]

devrait éviter d'avoir à rouler votre propre méthode de catégorie

20
répondu dmpontifex 2013-09-21 00:20:19

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.)

6
répondu Ben Mosher 2011-04-07 21:09:52

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];
4
répondu mr-sk 2010-02-04 04:51:48

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
2
répondu quellish 2013-11-04 06:13:23

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;
}
0
répondu Bill Cheswick 2013-05-16 20:39:19