【问题标题】:How to Base64 encoding on the iPhone如何在 iPhone 上进行 Base64 编码
【发布时间】:2009-05-19 11:52:42
【问题描述】:

如何在 iPhone 上进行 Base64 编码?

我发现了一些看起来很有希望的例子,但它们中的任何一个都无法在手机上工作。

【问题讨论】:

标签: objective-c iphone encoding base64


【解决方案1】:

你可以看一个例子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);

【讨论】:

  • 哇,直到 iOS 7 才在 NSData 中使用 base 64 编码。
【解决方案2】:

使用this库对Base64进行编码。

还支持ARC

【讨论】:

  • 现已弃用
【解决方案3】:

我也很难找到我能理解的 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;
}

【讨论】:

  • 将此代码与 ARC 一起使用时遇到了很多问题。我的应用随机崩溃了。
  • 计算输出长度有什么问题?
  • 嗨@kdda,我知道这已经回答了一段时间了。想知道你是否有这个解码器?谢谢!
  • 1) 分配的缓冲区太小导致内存损坏和崩溃。我冒昧地通过编辑来修复它。 2)您的长度计算过于复杂。一个简单的(inLength+2)/3*4 还不够吗?
  • 这个答案在Is copy & paste programming bad?中被引用。
【解决方案4】:

GitHub下载以下两个文件

Base64.h
Base64.m

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

在需要的文件中导入头文件

#import "Base64.h"

并使用 as 进行编码

NSString *plainText = @"Your String";

NSString *base64String = [plainText base64EncodedStringWithWrapWidth:0];

您也可以将其解码为

NSString *plainText = [base64String base64DecodedString];

【讨论】:

  • initWithBase64Encoding 已弃用。这些课程需要更新。
【解决方案5】:

试试这个...这对我来说非常有效。创建一个类别 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);

【讨论】:

    【解决方案6】:

    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 
    

    【讨论】:

      【解决方案7】:

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

      • base64EncodedDataWithOptions: – base64EncodedStringWithOptions:

      【讨论】:

        【解决方案8】:

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

        【讨论】:

          【解决方案9】:

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

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

          【讨论】:

            猜你喜欢
            • 2011-10-18
            • 2011-09-05
            • 1970-01-01
            • 1970-01-01
            • 2011-04-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多