我想进行base64编码和解码,但我无法从iPhone SDK中找到任何支持。我怎么能做base64编码和解码与或没有一个库?


当前回答

在mvds的出色改进中,存在两个问题。更改代码如下:

raw = tmpbuf;
inp = 0;
outbuf[outp++] = base64EncodingTable[(raw[inp] & 0xFC) >> 2];
outbuf[outp++] = base64EncodingTable[((raw[inp] & 0x03) << 4) | ((raw[inp+1] & 0xF0) >> 4)];
if ( left == 2 ) outbuf[outp++] = base64EncodingTable[((raw[inp+1] & 0x0F) << 2) | ((raw[inp+2] & 0xC0) >> 6)];
else outbuf[outp++] = '=';
outbuf[outp++] = '=';

其他回答

在mvds的出色改进中,存在两个问题。更改代码如下:

raw = tmpbuf;
inp = 0;
outbuf[outp++] = base64EncodingTable[(raw[inp] & 0xFC) >> 2];
outbuf[outp++] = base64EncodingTable[((raw[inp] & 0x03) << 4) | ((raw[inp+1] & 0xF0) >> 4)];
if ( left == 2 ) outbuf[outp++] = base64EncodingTable[((raw[inp+1] & 0x0F) << 2) | ((raw[inp+2] & 0xC0) >> 6)];
else outbuf[outp++] = '=';
outbuf[outp++] = '=';

我想这会有帮助的

 + (NSString *)toBase64String:(NSString *)string {
    NSData *data = [string dataUsingEncoding: NSUnicodeStringEncoding];

    NSString *ret = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

    return ret;
    }

    + (NSString *)fromBase64String:(NSString *)string {
NSData *aData = [string dataUsingEncoding:NSUTF8StringEncoding];
NSData *aDataDecoded = [[NSData alloc]initWithBase64EncodedString:string options:0];
NSString *decryptedStr = [[NSString alloc]initWithData:aDataDecoded encoding:NSUTF8StringEncoding];

return [decryptedStr autorelease];

}

因为这似乎是在base64编码和iphone上排名第一的谷歌,我想用上面的代码片段分享我的经验。

它是有效的,但是非常慢。在本机iphone上对随机图像(0.4 mb)进行基准测试需要37秒。主要原因可能是OOP的魔力——单字符nsstring等,只有在编码完成后才会自动释放。

这里发布的另一个建议(ab)使用openssl库,这感觉也有点过分。

下面的代码需要70毫秒——这是500倍的加速。这只做base64编码(解码将遵循一旦我遇到它)

+ (NSString *) base64StringFromData: (NSData *)data length: (int)length {
int lentext = [data length]; 
if (lentext < 1) return @"";

char *outbuf = malloc(lentext*4/3+4); // add 4 to be sure

if ( !outbuf ) return nil;

const unsigned char *raw = [data bytes];

int inp = 0;
int outp = 0;
int do_now = lentext - (lentext%3);

for ( outp = 0, inp = 0; inp < do_now; inp += 3 )
{
    outbuf[outp++] = base64EncodingTable[(raw[inp] & 0xFC) >> 2];
    outbuf[outp++] = base64EncodingTable[((raw[inp] & 0x03) << 4) | ((raw[inp+1] & 0xF0) >> 4)];
    outbuf[outp++] = base64EncodingTable[((raw[inp+1] & 0x0F) << 2) | ((raw[inp+2] & 0xC0) >> 6)];
    outbuf[outp++] = base64EncodingTable[raw[inp+2] & 0x3F];
}

if ( do_now < lentext )
{
    char tmpbuf[2] = {0,0};
    int left = lentext%3;
    for ( int i=0; i < left; i++ )
    {
        tmpbuf[i] = raw[do_now+i];
    }
    raw = tmpbuf;
    outbuf[outp++] = base64EncodingTable[(raw[inp] & 0xFC) >> 2];
    outbuf[outp++] = base64EncodingTable[((raw[inp] & 0x03) << 4) | ((raw[inp+1] & 0xF0) >> 4)];
    if ( left == 2 ) outbuf[outp++] = base64EncodingTable[((raw[inp+1] & 0x0F) << 2) | ((raw[inp+2] & 0xC0) >> 6)];
}

NSString *ret = [[[NSString alloc] initWithBytes:outbuf length:outp encoding:NSASCIIStringEncoding] autorelease];
free(outbuf);

return ret;
}

我省略了行切割,因为我不需要它,但添加它是微不足道的。

对于那些对优化感兴趣的人来说:目标是最小化主循环中发生的事情。因此,处理最后3个字节的所有逻辑都在循环之外处理。

此外,尝试就地处理数据,而不需要额外地从缓冲区复制数据。把所有算术运算都简化到最小。

观察那些放在一起查找表中的条目的位,当它们被放在一起而不移动时,它们不会重叠。因此,一个主要的改进可能是使用4个单独的256字节查找表并消除移位,如下所示:

outbuf[outp++] = base64EncodingTable1[(raw[inp] & 0xFC)];
outbuf[outp++] = base64EncodingTable2[(raw[inp] & 0x03) | (raw[inp+1] & 0xF0)];
outbuf[outp++] = base64EncodingTable3[(raw[inp+1] & 0x0F) | (raw[inp+2] & 0xC0)];
outbuf[outp++] = base64EncodingTable4[raw[inp+2] & 0x3F];

当然,你可以更进一步,但这超出了这里的范围。

根据您的要求,我已经使用Swift 4创建了一个示例演示,您可以根据您的要求编码/解码字符串和图像。

I have also added sample methods of relevant operations. // // Base64VC.swift // SOF_SortArrayOfCustomObject // // Created by Test User on 09/01/18. // Copyright © 2018 Test User. All rights reserved. // import UIKit import Foundation class Base64VC: NSObject { //---------------------------------------------------------------- // MARK:- // MARK:- String to Base64 Encode Methods //---------------------------------------------------------------- func sampleStringEncodingAndDecoding() { if let base64String = self.base64Encode(string: "TestString") { print("Base64 Encoded String: \n\(base64String)") if let originalString = self.base64Decode(base64String: base64String) { print("Base64 Decoded String: \n\(originalString)") } } } //---------------------------------------------------------------- func base64Encode(string: String) -> String? { if let stringData = string.data(using: .utf8) { return stringData.base64EncodedString() } return nil } //---------------------------------------------------------------- func base64Decode(base64String: String) -> String? { if let base64Data = Data(base64Encoded: base64String) { return String(data: base64Data, encoding: .utf8) } return nil } //---------------------------------------------------------------- // MARK:- // MARK:- Image to Base64 Encode Methods //---------------------------------------------------------------- func sampleImageEncodingAndDecoding() { if let base64ImageString = self.base64Encode(image: UIImage.init(named: "yourImageName")!) { print("Base64 Encoded Image: \n\(base64ImageString)") if let originaImage = self.base64Decode(base64ImageString: base64ImageString) { print("originalImageData \n\(originaImage)") } } } //---------------------------------------------------------------- func base64Encode(image: UIImage) -> String? { if let imageData = UIImagePNGRepresentation(image) { return imageData.base64EncodedString() } return nil } //---------------------------------------------------------------- func base64Decode(base64ImageString: String) -> UIImage? { if let base64Data = Data(base64Encoded: base64ImageString) { return UIImage(data: base64Data)! } return nil } }

更好的解决方案:

NSData中有一个内置函数

[data base64Encoding]; //iOS < 7.0
[data base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength]; //iOS >= 7.0