2009-05-19 4 views
30

Как мне кодировать Base64 на iPhone?Как кодировать Base64 на iPhone

Я нашел несколько примеров, которые выглядели многообещающими, но никогда не могли заставить их работать на телефоне.

+0

Может быть, этот небольшой фрагмент кода работает на iPhone тоже: http://stackoverflow.com/a/14522792/200321 – denis2342

ответ

45

Вы можете увидеть пример here.

Это для iOS7 +.

скопировать код здесь, на всякий случай:

// 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

Ничего себе, кодировка базы 64 не была в NSData до iOS 7. –

+0

Декодированная возвращает пустую строку для меня ?? Зачем –

10

У меня также возникли проблемы с поиском рабочего кода для iPhone, который я мог понять.

Я, наконец, написал это.

-(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

может у пожалуйста пост аналогичный код для дешифрования – MaheshBabu

+0

было много проблем при использовании этого кода ARC. Мое приложение разбилось случайным образом. – Peter

+0

Хорошее короткое решение, похоже, работает. Благодаря! – Stas

10

Использование this библиотека для кодирования Base64.

Он также поддерживает ARC

+0

В настоящее время устарел –

0

метод в 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

Я сделал свою собственную реализацию, где была удалена все проверки внутри цикла. Таким образом, на большом количестве данных он работает быстрее. Вы можете принять это за основу для собственного решения.

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

Попробуйте это ... это работало отлично для me.create категории Base64.h и Base 64.m, импорт в любой класс, который вы хотите использовать, и вызвать его, используя одну линию для базовой 64 кодирования для бывает.

// 
// 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

Скачать следующие два файла из GitHub

Base64.h 
Base64.m 

Добавьте эти файлы в свой проект заголовочный файл

Импорт в нужном файле

#import "Base64.h" 

И использовать, чтобы кодировать

NSString *plainText = @"Your String"; 

NSString *base64String = [plainText base64EncodedStringWithWrapWidth:0]; 

Также вы можете расшифровать его как

NSString *plainText = [base64String base64DecodedString]; 
+0

'initWithBase64Encoding' устарел. Эти кланы нуждаются в обновлении. – user2070775

2

кажется от прошивкой 7 вы больше не нужны никакие библиотеки для кодирования в Base64. Эти методы на NSData могут быть использованы для Base64 кодирования:

  • base64EncodedDataWithOptions: - base64EncodedStringWithOptions:
2

reference

NSString *plainString = @"foo"; 

Кодирование

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

Декодирование

NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:base64String options:0]; 
NSString *decodedString = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding]; 
NSLog(@"%@", decodedString); // foo 
Смежные вопросы