如何在 iOS 上进行 base64 编码?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/392464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 15:28:04  来源:igfitidea点击:

How do I do base64 encoding on iOS?

iosobjective-cbase64

提问by BlueDolphin

I'd like to do base64encoding and decoding, but I could not find any support from the iPhone SDK. How can I do base64encoding and decoding with or without a library?

我想做base64编码和解码,但我找不到 iPhone 的任何支持SDK。如何base64使用或不使用库进行编码和解码?

回答by Alex Reynolds

This is a good use case for Objective C categories.

这是 Objective C类别的一个很好的用例。

For Base64 encoding:

对于 Base64 编码:

#import <Foundation/NSString.h>

@interface NSString (NSStringAdditions)

+ (NSString *) base64StringFromData:(NSData *)data length:(int)length;

@end

-------------------------------------------

#import "NSStringAdditions.h"

static char base64EncodingTable[64] = {
  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
  'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
  'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
  'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};

@implementation NSString (NSStringAdditions)

+ (NSString *) base64StringFromData: (NSData *)data length: (int)length {
  unsigned long ixtext, lentext;
  long ctremaining;
  unsigned char input[3], output[4];
  short i, charsonline = 0, ctcopy;
  const unsigned char *raw;
  NSMutableString *result;

  lentext = [data length]; 
  if (lentext < 1)
    return @"";
  result = [NSMutableString stringWithCapacity: lentext];
  raw = [data bytes];
  ixtext = 0; 

  while (true) {
    ctremaining = lentext - ixtext;
    if (ctremaining <= 0) 
       break;        
    for (i = 0; i < 3; i++) { 
       unsigned long ix = ixtext + i;
       if (ix < lentext)
          input[i] = raw[ix];
       else
  input[i] = 0;
  }
  output[0] = (input[0] & 0xFC) >> 2;
  output[1] = ((input[0] & 0x03) << 4) | ((input[1] & 0xF0) >> 4);
  output[2] = ((input[1] & 0x0F) << 2) | ((input[2] & 0xC0) >> 6);
  output[3] = input[2] & 0x3F;
  ctcopy = 4;
  switch (ctremaining) {
    case 1: 
      ctcopy = 2; 
      break;
    case 2: 
      ctcopy = 3; 
      break;
  }

  for (i = 0; i < ctcopy; i++)
     [result appendString: [NSString stringWithFormat: @"%c", base64EncodingTable[output[i]]]];

  for (i = ctcopy; i < 4; i++)
     [result appendString: @"="];

  ixtext += 3;
  charsonline += 4;

  if ((length > 0) && (charsonline >= length))
    charsonline = 0;
  }     
  return result;
}

@end

For Base64 decoding:

对于 Base64 解码:

#import <Foundation/Foundation.h>

@class NSString;

@interface NSData (NSDataAdditions)

+ (NSData *) base64DataFromString:(NSString *)string;

@end

-------------------------------------------

#import "NSDataAdditions.h"

@implementation NSData (NSDataAdditions)

+ (NSData *)base64DataFromString: (NSString *)string
{
    unsigned long ixtext, lentext;
    unsigned char ch, inbuf[4], outbuf[3];
    short i, ixinbuf;
    Boolean flignore, flendtext = false;
    const unsigned char *tempcstring;
    NSMutableData *theData;

    if (string == nil)
    {
        return [NSData data];
    }

    ixtext = 0;

    tempcstring = (const unsigned char *)[string UTF8String];

    lentext = [string length];

    theData = [NSMutableData dataWithCapacity: lentext];

    ixinbuf = 0;

    while (true)
    {
        if (ixtext >= lentext)
        {
            break;
        }

        ch = tempcstring [ixtext++];

        flignore = false;

        if ((ch >= 'A') && (ch <= 'Z'))
        {
            ch = ch - 'A';
        }
        else if ((ch >= 'a') && (ch <= 'z'))
        {
            ch = ch - 'a' + 26;
        }
        else if ((ch >= '0') && (ch <= '9'))
        {
            ch = ch - '0' + 52;
        }
        else if (ch == '+')
        {
            ch = 62;
        }
        else if (ch == '=')
        {
            flendtext = true;
        }
        else if (ch == '/')
        {
            ch = 63;
        }
        else
        {
            flignore = true; 
        }

        if (!flignore)
        {
            short ctcharsinbuf = 3;
            Boolean flbreak = false;

            if (flendtext)
            {
                if (ixinbuf == 0)
                {
                    break;
                }

                if ((ixinbuf == 1) || (ixinbuf == 2))
                {
                    ctcharsinbuf = 1;
                }
                else
                {
                    ctcharsinbuf = 2;
                }

                ixinbuf = 3;

                flbreak = true;
            }

            inbuf [ixinbuf++] = ch;

            if (ixinbuf == 4)
            {
                ixinbuf = 0;

                outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0x30) >> 4);
                outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
                outbuf[2] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F);

                for (i = 0; i < ctcharsinbuf; i++)
                {
                    [theData appendBytes: &outbuf[i] length: 1];
                }
            }

            if (flbreak)
            {
                break;
            }
        }
    }

    return theData;
}

    @end

回答by Mike Ho

A really, really fast implementation which was ported (and modified/improved) from the PHP Core library into native Objective-C code is available in the QSStrings Classfrom the QSUtilities Library. I did a quick benchmark: a 5.3MB image (JPEG) file took < 50ms to encode, and about 140ms to decode.

这是从PHP Core库成原生Objective-C代码移植(和改性/改善)一个非常,非常快速的实施是在可用QSSt​​rings类QSUtilities库。我做了一个快速的基准测试:一个 5.3MB 的图像 (JPEG) 文件需要 < 50 毫秒来编码,大约 140 毫秒来解码。

The code for the entire library (including the Base64 Methods) are available on GitHub.

整个库的代码(包括 Base64 方法)可在GitHub找到

Or alternatively, if you want the code to justthe Base64 methods themselves, I've posted it here:

或者,如果您希望代码用于 Base64 方法本身,我已将其发布在此处:

First, you need the mapping tables:

首先,您需要映射表:

static const char _base64EncodingTable[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const short _base64DecodingTable[256] = {
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -1, -1, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2,
    -2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2,
    -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
};

To Encode:

编码:

+ (NSString *)encodeBase64WithString:(NSString *)strData {
    return [QSStrings encodeBase64WithData:[strData dataUsingEncoding:NSUTF8StringEncoding]];
}

+ (NSString *)encodeBase64WithData:(NSData *)objData {
    const unsigned char * objRawData = [objData bytes];
    char * objPointer;
    char * strResult;

    // Get the Raw Data length and ensure we actually have data
    int intLength = [objData length];
    if (intLength == 0) return nil;

    // Setup the String-based Result placeholder and pointer within that placeholder
    strResult = (char *)calloc((((intLength + 2) / 3) * 4) + 1, sizeof(char));
    objPointer = strResult;

    // Iterate through everything
    while (intLength > 2) { // keep going until we have less than 24 bits
        *objPointer++ = _base64EncodingTable[objRawData[0] >> 2];
        *objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)];
        *objPointer++ = _base64EncodingTable[((objRawData[1] & 0x0f) << 2) + (objRawData[2] >> 6)];
        *objPointer++ = _base64EncodingTable[objRawData[2] & 0x3f];

        // we just handled 3 octets (24 bits) of data
        objRawData += 3;
        intLength -= 3; 
    }

    // now deal with the tail end of things
    if (intLength != 0) {
        *objPointer++ = _base64EncodingTable[objRawData[0] >> 2];
        if (intLength > 1) {
            *objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)];
            *objPointer++ = _base64EncodingTable[(objRawData[1] & 0x0f) << 2];
            *objPointer++ = '=';
        } else {
            *objPointer++ = _base64EncodingTable[(objRawData[0] & 0x03) << 4];
            *objPointer++ = '=';
            *objPointer++ = '=';
        }
    }

    // Terminate the string-based result
    *objPointer = '
+ (NSData *)decodeBase64WithString:(NSString *)strBase64 {
    const char *objPointer = [strBase64 cStringUsingEncoding:NSASCIIStringEncoding];
    size_t intLength = strlen(objPointer);
    int intCurrent;
    int i = 0, j = 0, k;

    unsigned char *objResult = calloc(intLength, sizeof(unsigned char));

    // Run through the whole string, converting as we go
    while ( ((intCurrent = *objPointer++) != '
NSString *string;

if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
    string = [data base64EncodedStringWithOptions:kNilOptions];  // iOS 7+
} else {
    string = [data base64Encoding];                              // pre iOS7
}
') && (intLength-- > 0) ) { if (intCurrent == '=') { if (*objPointer != '=' && ((i % 4) == 1)) {// || (intLength > 0)) { // the padding character is invalid at this point -- so this entire string is invalid free(objResult); return nil; } continue; } intCurrent = _base64DecodingTable[intCurrent]; if (intCurrent == -1) { // we're at a whitespace -- simply skip over continue; } else if (intCurrent == -2) { // we're at an invalid character free(objResult); return nil; } switch (i % 4) { case 0: objResult[j] = intCurrent << 2; break; case 1: objResult[j++] |= intCurrent >> 4; objResult[j] = (intCurrent & 0x0f) << 4; break; case 2: objResult[j++] |= intCurrent >>2; objResult[j] = (intCurrent & 0x03) << 6; break; case 3: objResult[j++] |= intCurrent; break; } i++; } // mop things up if we ended on a boundary k = j; if (intCurrent == '=') { switch (i % 4) { case 1: // Invalid state free(objResult); return nil; case 2: k++; // flow through case 3: objResult[k] = 0; } } // Cleanup and setup the return NSData NSData * objData = [[[NSData alloc] initWithBytes:objResult length:j] autorelease]; free(objResult); return objData; }
'; // Create result NSString object NSString *base64String = [NSString stringWithCString:strResult encoding:NSASCIIStringEncoding]; // Free memory free(strResult); return base64String; }

To Decode:

解码:

NSData *data;

if ([NSData instancesRespondToSelector:@selector(initWithBase64EncodedString:options:)]) {
    data = [[NSData alloc] initWithBase64EncodedString:string options:kNilOptions];  // iOS 7+
} else {
    data = [[NSData alloc] initWithBase64Encoding:string];                           // pre iOS7
}

回答by Rob

Historically we would have directed you to one of the many third-party base 64 libraries (as discussed in the other answers) for converting from binary data to base 64 string (and back), but iOS 7 now has native base 64 encoding(and exposes the previously private iOS 4 methods, in case you need to support earlier versions of iOS).

从历史上看,我们会引导您使用许多第三方 base 64 库之一(如其他答案中所述)以将二进制数据转换为 base 64 字符串(并返回),但 iOS 7 现在具有原生 base 64 编码(和公开以前私有的 iOS 4 方法,以防您需要支持早期版本的 iOS)。

Thus to convert NSDatato NSStringbase 64 representation you can use base64EncodedStringWithOptions. If you have to support iOS versions prior to 7.0 as well, you can do:

因此,要转换NSDataNSStringbase 64 表示,您可以使用base64EncodedStringWithOptions. 如果您还必须支持 7.0 之前的 iOS 版本,您可以执行以下操作:

NSString *string = [data base64EncodedStringWithOptions:kNilOptions];

And to convert base 64 NSStringback to NSDatayou can use initWithBase64EncodedString. Likewise, if you need to support iOS versions prior to 7.0, you can do:

并将 base 64 转换NSStringNSData您可以使用initWithBase64EncodedString. 同样,如果您需要支持 7.0 之前的 iOS 版本,您可以执行以下操作:

NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:kNilOptions]; 


Obviously, if you don't need backward compatibility with iOS versions prior to 7.0, it's even easier, just use base64EncodedStringWithOptionsor initWithBase64EncodedString, respectively, and don't bother with the run-time check for earlier iOS versions. In fact, if you use the above code when your minimum target is iOS 7 or greater, you'll actually get a compiler warning about the deprecated methods. So, in iOS 7 and greater, you would simply convert to base 64 string with:

显然,如果您不需要与 7.0 之前的 iOS 版本向后兼容,那就更简单了,只需分别使用base64EncodedStringWithOptionsinitWithBase64EncodedString,并且不要打扰早期iOS 版本的运行时检查。事实上,如果您在最低目标是 iOS 7 或更高版本时使用上述代码,您实际上会收到有关已弃用方法的编译器警告。因此,在 iOS 7 及更高版本中,您只需使用以下命令转换为 base 64 字符串:

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

and back again with:

并再次返回:

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

回答by quellish

iOS includes built in support for base64 encoding and decoding. If you look at resolv.hyou should see the two functions b64_ntopand b64_pton. The Square SocketRocketlibrary provides a reasonable example of how to use these functions from objective-c.

iOS 包括对 base64 编码和解码的内置支持。如果您看一下,resolv.h您应该会看到两个函数b64_ntopb64_pton。Square SocketRocket库提供了一个合理的示例,说明如何使用 Objective-c 中的这些函数。

These functions are pretty well tested and reliable - unlike many of the implementations you may find in random internet postings. Don't forget to link against libresolv.dylib.

这些功能经过了很好的测试和可靠 - 与您可能在随机互联网发布中找到的许多实现不同。不要忘记链接到libresolv.dylib.

回答by mvds

Since this seems to be the number one google hit on base64 encoding and iphone, I felt like sharing my experience with the code snippet above.

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

It works, but it is extremely slow. A benchmark on a random image (0.4 mb) took 37 seconds on native iphone. The main reason is probably all the OOP magic - single char NSStrings etc, which are only autoreleased after the encoding is done.

它有效,但速度非常慢。对随机图像 (0.4 mb) 的基准测试在原生 iphone 上耗时 37 秒。主要原因可能是所有的 OOP 魔法——单字符 NSStrings 等,它们只有在编码完成后才会自动释放。

Another suggestion posted here (ab)uses the openssl library, which feels like overkill as well.

此处发布的另一个建议 (ab) 使用了 openssl 库,这也感觉有点矫枉过正。

The code below takes 70 ms - that's a 500 times speedup. This only does base64 encoding (decoding will follow as soon as I encounter it)

下面的代码需要 70 毫秒 - 这是 500 倍的加速。这只进行base64编码(我一遇到它就会解码)

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++] = '=';

I left out the line-cutting since I didn't need it, but it's trivial to add.

由于我不需要它,所以我省略了线切割,但添加起来很简单。

For those who are interested in optimizing: the goal is to minimize what happens in the main loop. Therefore all logic to deal with the last 3 bytes is treated outside the loop.

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

Also, try to work on data in-place, without additional copying to/from buffers. And reduce any arithmetic to the bare minimum.

此外,尝试就地处理数据,而无需向/从缓冲区进行额外的复制。并将任何算术减少到最低限度。

Observe that the bits that are put together to look up an entry in the table, would not overlap when they were to be orred together without shifting. A major improvement could therefore be to use 4 separate 256 byte lookup tables and eliminate the shifts, like this:

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

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

Of course you could take it a whole lot further, but that's beyond the scope here.

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

回答by user335742

In mvds's excellent improvement, there are two problems. Change code to this:

在mvds的出色改进中,存在两个问题。将代码改成这样:

unsigned char tmpbuf[3] = {0,0,0};

回答by Nagaraj

Better solution :

更好的解决方案:

There is a built in function in NSData

NSData 中有一个内置函数

while ( outp%4 ) outbuf[outp++] = '=';

回答by AlexeyVMP

Under iOS8 and later use - (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)optionsof NSData

在 iOS8 及更高版本下使用- (NSString *)base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)optionsNSData

回答by mvds

Glad people liked it. The end-game was a little flawed I must admit. Besides rightly setting inp=0 you should either also increase tmpbuf's size to 3, like

很高兴人们喜欢它。我必须承认,最终游戏有点缺陷。除了正确设置 inp=0 之外,您还应该将 tmpbuf 的大小增加到 3,例如

#import "NSDataAdditions.h"
@implementation NSData (NSDataAdditions)

+ (NSData *) base64DataFromString: (NSString *)string {
  unsigned long ixtext, lentext;
  unsigned char ch, input[4], output[3];
  short i, ixinput;
  Boolean flignore, flendtext = false;
  const char *temporary;
  NSMutableData *result;

  if (!string)
    return [NSData data];

  ixtext = 0;
  temporary = [string UTF8String];
  lentext = [string length];
  result = [NSMutableData dataWithCapacity: lentext];
  ixinput = 0;

  while (true) {
    if (ixtext >= lentext)
      break;
    ch = temporary[ixtext++];
    flignore = false;

    if ((ch >= 'A') && (ch <= 'Z'))
      ch = ch - 'A';
    else if ((ch >= 'a') && (ch <= 'z'))
      ch = ch - 'a' + 26;
    else if ((ch >= '0') && (ch <= '9'))
      ch = ch - '0' + 52;
    else if (ch == '+')
      ch = 62;
    else if (ch == '=')
      flendtext = true;
    else if (ch == '/')
      ch = 63;
    else
      flignore = true;

    if (!flignore) {
      short ctcharsinput = 3;
      Boolean flbreak = false;

      if (flendtext) {
         if (ixinput == 0)
           break;              
         if ((ixinput == 1) || (ixinput == 2))
           ctcharsinput = 1;
         else
           ctcharsinput = 2;
         ixinput = 3;
         flbreak = true;
      }

      input[ixinput++] = ch;

      if (ixinput == 4){
        ixinput = 0;
        output[0] = (input[0] << 2) | ((input[1] & 0x30) >> 4);
        output[1] = ((input[1] & 0x0F) << 4) | ((input[2] & 0x3C) >> 2);
        output[2] = ((input[2] & 0x03) << 6) | (input[3] & 0x3F);
        for (i = 0; i < ctcharsinput; i++)
        [result appendBytes: &output[i] length: 1];
      }
    if (flbreak)
      break;
    }
  }
  return result;
}
@end

orleave out the orring of raw[inp+2]; if we would have a raw[inp+2] != 0 for this chunk we would still be in the loop of course...

省略 raw[inp+2] 的 orring;如果我们有一个 raw[inp+2] != 0 对于这个块,我们当然仍然在循环中......

Either way works, you might consider keeping the final table lookup block identical to the one in the loop for clarity. In the final version I used I did

无论哪种方式都有效,为了清晰起见,您可能会考虑将最终表查找块与循环中的块保持相同。在我使用的最终版本中,我做了

##代码##

To add the ==

添加 ==

Sorry I didn't check RFC's and stuff, should have done a better job!

抱歉,我没有检查 RFC 和其他东西,应该做得更好!

回答by alpha09jp

##代码##