Как кодировать Base64 на iPhone - PullRequest
35 голосов
/ 19 мая 2009

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

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

Ответы [ 9 ]

53 голосов
/ 28 июня 2014

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

Это для 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);
10 голосов
/ 07 января 2013

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

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

10 голосов
/ 05 августа 2010

У меня также были проблемы с поиском рабочего кода для 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[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    //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;
}
4 голосов
/ 02 мая 2013

Попробуйте ... это отлично сработало для меня. Создайте категории Base64.h и Base 64.m. Импортируйте в любой класс, который вы хотите использовать, и вызывайте его, используя одну строку для кодирования Base 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[] = 
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
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];
}

@ конец

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 голосов
/ 31 августа 2016

ссылка

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 
3 голосов
/ 23 сентября 2013

Загрузка следующих двух файлов из GitHub

Base64.h
Base64.m

Добавьте эти файлы в ваш проект

Импортировать заголовочный файл в нужный файл

#import "Base64.h"

И использовать как для кодирования

NSString *plainText = @"Your String";

NSString *base64String = [plainText base64EncodedStringWithWrapWidth:0];

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

NSString *plainText = [base64String base64DecodedString];
2 голосов
/ 05 февраля 2014

Похоже, с iOS 7 вам больше не нужны библиотеки для кодирования в Base64. Для кодирования Base64 могут использоваться следующие методы для NSData :

  • base64EncodedDataWithOptions: - base64EncodedStringWithOptions:
0 голосов
/ 18 апреля 2013

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

static char *alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

+ (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;
}
0 голосов
/ 07 января 2013

метод в категории NSData

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

    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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...