2009-05-19 17 views
30

¿Cómo hago la codificación Base64 en el iPhone?Cómo codificar Base64 en el iPhone

He encontrado algunos ejemplos que parecían prometedores, pero nunca conseguí que ninguno de ellos funcionara en el teléfono.

+0

Tal vez este pequeño fragmento de código funciona en el iPhone también: http://stackoverflow.com/a/14522792/200321 – denis2342

Respuesta

45

Se puede ver un ejemplo here.

Esto es para iOS7 +.

copio el código aquí, por si acaso:

// Create NSData object 
NSData *nsdata = [@"iOS Developer Tips encoded in Base64" 
    dataUsingEncoding:NSUTF8StringEncoding]; 

// Get NSString from NSData object in Base64 
NSString *base64Encoded = [nsdata base64EncodedStringWithOptions:0]; 

// Print the Base64 encoded string 
NSLog(@"Encoded: %@", base64Encoded); 

// Let's go the other way... 

// NSData from the Base64 encoded str 
NSData *nsdataFromBase64String = [[NSData alloc] 
    initWithBase64EncodedString:base64Encoded options:0]; 

// Decoded NSString from the NSData 
NSString *base64Decoded = [[NSString alloc] 
    initWithData:nsdataFromBase64String encoding:NSUTF8StringEncoding]; 
NSLog(@"Decoded: %@", base64Decoded); 
+0

Wow, la codificación de la base 64 no estaba en NSData hasta iOS 7. –

+0

El decodificador devuelve una cadena vacía para mí ?? por qué –

10

También tuve problemas para encontrar un código de trabajo para el iPhone que pudiera entender.

Finalmente escribí esto.

-(NSString *)Base64Encode:(NSData *)data; 

-(NSString *)Base64Encode:(NSData *)data{ 

    //Point to start of the data and set buffer sizes 
    int inLength = [data length]; 
    int outLength = ((((inLength * 4)/3)/4)*4) + (((inLength * 4)/3)%4 ? 4 : 0); 
    const char *inputBuffer = [data bytes]; 
    char *outputBuffer = malloc(outLength+1); 
    outputBuffer[outLength] = 0; 

    //64 digit code 
    static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 

    //Start the count 
    int cycle = 0; 
    int inpos = 0; 
    int outpos = 0; 
    char temp; 

    //Pad the last to bytes, the outbuffer must always be a multiple of 4. 
    outputBuffer[outLength-1] = '='; 
    outputBuffer[outLength-2] = '='; 

    /* http://en.wikipedia.org/wiki/Base64 

     Text content  M   a   n 
     ASCII   77  97  110 
     8 Bit pattern 01001101 01100001 01101110 

     6 Bit pattern 010011 010110 000101 101110 
     Index   19  22  5   46 
     Base64-encoded T   W   F   u 
    */ 

    while (inpos < inLength){ 
     switch (cycle) { 

      case 0: 
       outputBuffer[outpos++] = Encode[(inputBuffer[inpos] & 0xFC) >> 2]; 
       cycle = 1; 
       break; 

      case 1: 
       temp = (inputBuffer[inpos++] & 0x03) << 4; 
       outputBuffer[outpos] = Encode[temp]; 
       cycle = 2; 
       break; 

      case 2: 
       outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xF0) >> 4]; 
       temp = (inputBuffer[inpos++] & 0x0F) << 2; 
       outputBuffer[outpos] = Encode[temp]; 
       cycle = 3; 
       break; 

      case 3: 
       outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xC0) >> 6]; 
       cycle = 4; 
       break; 

      case 4: 
       outputBuffer[outpos++] = Encode[inputBuffer[inpos++] & 0x3f]; 
       cycle = 0; 
       break; 

      default: 
       cycle = 0; 
       break; 
     } 
    } 
    NSString *pictemp = [NSString stringWithUTF8String:outputBuffer]; 
    free(outputBuffer); 
    return pictemp; 
} 
+1

puede u pls de código postal similar para el descifrado – MaheshBabu

+0

tenido un montón de problemas durante el uso de este código con ARCO. Mi aplicación se colgó al azar. – Peter

+0

Buena solución corta, parece estar funcionando. ¡Gracias! – Stas

10

Uso this biblioteca para codificar Base64.

También es compatible con ARC

+0

Ahora está en desuso –

0

Un método en una categoría NSData

- (NSString*)encodeBase64 {  
    static char* alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/="; 

    unsigned int length = self.length; 
    unsigned const char* rawData = self.bytes; 

    //empty data = empty output 
    if (length == 0) { 
     return @""; 
    } 

    unsigned int outputLength = (((length + 2)/3) * 4); 

    //let's allocate buffer for the output 
    char* rawOutput = malloc(outputLength + 1); 

    //with each step we get 3 bytes from the input and write 4 bytes to the output 
    for (unsigned int i = 0, outputIndex = 0; i < length; i += 3, outputIndex += 4) { 
     BOOL triple = NO; 
     BOOL quad = NO; 

     //get 3 bytes (or only 1 or 2 when we have reached the end of input) 
     unsigned int value = rawData[i]; 
     value <<= 8; 

     if (i + 1 < length) { 
      value |= rawData[i + 1]; 
      triple = YES; 
     } 

     value <<= 8; 

     if (i + 2 < length) { 
      value |= rawData[i + 2]; 
      quad = YES; 
     } 

     //3 * 8 bits written as 4 * 6 bits (indexing the 64 chars of the alphabet) 
     //write = if end of input reached 
     rawOutput[outputIndex + 3] = (quad) ? alphabet[value & 0x3F] : '='; 
     value >>= 6; 
     rawOutput[outputIndex + 2] = (triple) ? alphabet[value & 0x3F] : '='; 
     value >>= 6; 
     rawOutput[outputIndex + 1] = alphabet[value & 0x3F]; 
     value >>= 6; 
     rawOutput[outputIndex] = alphabet[value & 0x3F]; 
    } 

    rawOutput[outputLength] = 0; 

    NSString* output = [NSString stringWithCString:rawOutput encoding:NSASCIIStringEncoding]; 

    free(rawOutput); 

    return output; 
} 
0

hice mi propia implementación, donde se ha eliminado todos los controles dentro del bucle. Entonces, con una gran cantidad de datos, funciona más rápido. Puede tomarlo como base para su propia solución.

static char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 

+ (NSString *)encodeString:(NSString *)data 
{ 
    const char *input = [data cStringUsingEncoding:NSUTF8StringEncoding]; 
    unsigned long inputLength = [data length]; 
    unsigned long modulo = inputLength % 3; 
    unsigned long outputLength = (inputLength/3) * 4 + (modulo ? 4 : 0); 
    unsigned long j = 0; 

    // Do not forget about trailing zero 
    unsigned char *output = malloc(outputLength + 1); 
    output[outputLength] = 0; 

    // Here are no checks inside the loop, so it works much faster than other implementations 
    for (unsigned long i = 0; i < inputLength; i += 3) { 
     output[j++] = alphabet[ (input[i] & 0xFC) >> 2 ]; 
     output[j++] = alphabet[ ((input[i] & 0x03) << 4) | ((input[i + 1] & 0xF0) >> 4) ]; 
     output[j++] = alphabet[ ((input[i + 1] & 0x0F)) << 2 | ((input[i + 2] & 0xC0) >> 6) ]; 
     output[j++] = alphabet[ (input[i + 2] & 0x3F) ]; 
    } 
    // Padding in the end of encoded string directly depends of modulo 
    if (modulo > 0) { 
     output[outputLength - 1] = '='; 
     if (modulo == 1) 
      output[outputLength - 2] = '='; 
    } 
    NSString *s = [NSString stringWithUTF8String:(const char *)output]; 
    free(output); 
    return s; 
} 
4

probar esto ... esto funcionó perfectamente para me.create una categoría Base64.h y la Base 64.m, Importar para cualquier clase que desea utilizar y llamarlo usando una sola línea de base 64 a la codificación ocurrir.

// 
// Base64.h 
// CryptTest 
// Created by SURAJ K THOMAS on 02/05/2013. 


#import <Foundation/Foundation.h> 


@interface Base64 : NSObject { 

} 
+ (void) initialize; 
+ (NSString*) encode:(const uint8_t*) input length:(NSInteger) length; 
+ (NSString*) encode:(NSData*) rawBytes; 
+ (NSData*) decode:(const char*) string length:(NSInteger) inputLength; 
+ (NSData*) decode:(NSString*) string; 
@end 





#import "Base64.h" 


@implementation Base64 
#define ArrayLength(x) (sizeof(x)/sizeof(*(x))) 

static char encodingTable[] = 
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz/"; 
static char decodingTable[128]; 

+ (void) initialize { 
if (self == [Base64 class]) { 
    memset(decodingTable, 0, ArrayLength(decodingTable)); 
    for (NSInteger i = 0; i < ArrayLength(encodingTable); i++) { 
     decodingTable[encodingTable[i]] = i; 
    } 
} 
} 


+ (NSString*) encode:(const uint8_t*) input length:(NSInteger) length { 
NSMutableData* data = [NSMutableData dataWithLength:((length + 2)/3) * 4]; 
uint8_t* output = (uint8_t*)data.mutableBytes; 

for (NSInteger i = 0; i < length; i += 3) { 
    NSInteger value = 0; 
    for (NSInteger j = i; j < (i + 3); j++) { 
     value <<= 8; 

     if (j < length) { 
      value |= (0xFF & input[j]); 
     } 
    } 

    NSInteger index = (i/3) * 4; 
    output[index + 0] =     encodingTable[(value >> 18) & 0x3F]; 
    output[index + 1] =     encodingTable[(value >> 12) & 0x3F]; 
    output[index + 2] = (i + 1) < length ? encodingTable[(value >> 6) & 0x3F] : '='; 
    output[index + 3] = (i + 2) < length ? encodingTable[(value >> 0) & 0x3F] : '='; 
} 

return [[NSString alloc] initWithData:data 
           encoding:NSASCIIStringEncoding]; 
} 


+ (NSString*) encode:(NSData*) rawBytes { 
return [self encode:(const uint8_t*) rawBytes.bytes length:rawBytes.length]; 
} 


+ (NSData*) decode:(const char*) string length:(NSInteger) inputLength { 
if ((string == NULL) || (inputLength % 4 != 0)) { 
    return nil; 
} 

while (inputLength > 0 && string[inputLength - 1] == '=') { 
    inputLength--; 
} 

NSInteger outputLength = inputLength * 3/4; 
NSMutableData* data = [NSMutableData dataWithLength:outputLength]; 
uint8_t* output = data.mutableBytes; 

NSInteger inputPoint = 0; 
NSInteger outputPoint = 0; 
while (inputPoint < inputLength) { 
    char i0 = string[inputPoint++]; 
    char i1 = string[inputPoint++]; 
    char i2 = inputPoint < inputLength ? string[inputPoint++] : 'A'; /* 'A' will 
decode to \0 */ 
    char i3 = inputPoint < inputLength ? string[inputPoint++] : 'A'; 

    output[outputPoint++] = (decodingTable[i0] << 2) | (decodingTable[i1] >> 4); 
    if (outputPoint < outputLength) { 
     output[outputPoint++] = ((decodingTable[i1] & 0xf) << 4) | 
(decodingTable[i2] >> 2); 
    } 
    if (outputPoint < outputLength) { 
     output[outputPoint++] = ((decodingTable[i2] & 0x3) << 6) | 
decodingTable[i3]; 
    } 
} 

return data; 
} 


+ (NSData*) decode:(NSString*) string { 
return [self decode:[string cStringUsingEncoding:NSASCIIStringEncoding] 
length:string.length]; 
} 

@end

now import the above category to any class and convert the string like below 


NSString *authString = [[NSString stringWithFormat:@"OD0EK819OJFIFT6OJZZXT09Y1YUT1EJ2"] 
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; 


NSData *inputData = [authString dataUsingEncoding:NSUTF8StringEncoding]; 

NSString *finalAuth =[Base64 encode:inputData]; 
NSLog(@"Encoded string =%@", finalAuth); 
3

Descargar siguientes dos archivos de GitHub

Base64.h 
Base64.m 

agregar estos archivos a su proyecto de archivo de cabecera

importación de archivo deseado

#import "Base64.h" 

y el uso como para codificar

NSString *plainText = @"Your String"; 

NSString *base64String = [plainText base64EncodedStringWithWrapWidth:0]; 

También se puede decodificar como

NSString *plainText = [base64String base64DecodedString]; 
+0

'initWithBase64Encoding' está en desuso. Esas clases necesitan una actualización. – user2070775

2

Parece como de iOS 7 ya no necesita ninguna biblioteca para codificar en Base64. Siguientes métodos en NSData se pueden utilizar para codificar Base64:

  • base64EncodedDataWithOptions: - base64EncodedStringWithOptions:
2

reference

NSString *plainString = @"foo"; 

Codificación

NSData *plainData = [plainString dataUsingEncoding:NSUTF8StringEncoding]; 
NSString *base64String = [plainData base64EncodedStringWithOptions:0]; 
NSLog(@"%@", base64String); // Zm9v 

decodificación

NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:base64String options:0]; 
NSString *decodedString = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding]; 
NSLog(@"%@", decodedString); // foo 
Cuestiones relacionadas