36

如何在 iPhone 上进行 Base64 编码?

我发现了一些看起来很有希望的例子,但永远无法让它们中的任何一个在电话上工作。

4

9 回答 9

61

你可以在这里看到一个例子。

这适用于 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);
于 2014-06-28T15:56:18.207 回答
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[] = "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;
}
于 2010-08-05T04:01:55.003 回答
10

使用库对 Base64 进行编码。

它还支持ARC

于 2013-01-07T10:45:12.820 回答
4

试试这个......这对我来说非常有效。创建一个类别 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);
于 2013-05-02T06:27:32.003 回答
4

从GitHub下载以下两个文件

Base64.h
Base64.m

将这些文件添加到您的项目中

在所需文件中导入头文件

#import "Base64.h"

并使用 as 进行编码

NSString *plainText = @"Your String";

NSString *base64String = [plainText base64EncodedStringWithWrapWidth:0];

您也可以将其解码为

NSString *plainText = [base64String base64DecodedString];
于 2013-09-23T10:47:32.140 回答
3

参考

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 
于 2016-08-31T20:29:50.793 回答
2

似乎从 iOS 7 开始,您不再需要任何库以使用 Base64 进行编码。NSData上的以下方法可用于 Base64 编码:

  • base64EncodedDataWithOptions: – base64EncodedStringWithOptions:
于 2014-02-04T20:31:50.580 回答
0

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;
}
于 2013-01-07T10:55:33.373 回答
0

我做了自己的实现,其中已删除循环内的所有检查。因此,在大量数据上,它的工作速度更快。您可以将其作为自己解决方案的基础。

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;
}
于 2013-04-18T09:28:20.967 回答