How to Base64 encoding on the iPhone

前端 未结 9 2072
情话喂你
情话喂你 2020-11-29 03:13

How do I do Base64 encoding on the iPhone?

I have found a few examples that looked promising, but could never get any of them to work on the phone.

相关标签:
9条回答
  • 2020-11-29 03:51

    Try this out...this worked perfectly for me.create a category Base64.h and Base 64.m,Import to any class you want to use and call it using single line for base 64 encoding to happen.

    //
    //  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];
    }
    

    @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);
    
    0 讨论(0)
  • 2020-11-29 03:55

    Use this library to encode Base64.

    It also supports ARC

    0 讨论(0)
  • 2020-11-29 03:55

    I did my own implementation, where has been removed all checks inside the loop. So on big amount of data, it works faster. You can take it as a basis for own solution.

    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 讨论(0)
  • 2020-11-29 03:56

    A method in a NSData category

    - (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;
    }
    
    0 讨论(0)
  • 2020-11-29 04:02

    reference

    NSString *plainString = @"foo";
    

    Encoding

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

    Decoding

    NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
    NSString *decodedString = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding];
    NSLog(@"%@", decodedString); // foo 
    
    0 讨论(0)
  • 2020-11-29 04:04

    I also had trouble finding working code for the iPhone that I could understand.

    I finally wrote this.

    -(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;
    }
    
    0 讨论(0)
提交回复
热议问题