iOS base64 编码详解

iOS中将NSData转为base64编码时有NSDataBase64EncodingOptions

NSDataBase64EncodingOptions有四个选项

/****************        Base 64 Options    ****************/

typedef NS_OPTIONS(NSUInteger, NSDataBase64EncodingOptions) {
    // Use zero or one of the following to control the maximum line length after which a line ending is inserted. No line endings are inserted by default.
    NSDataBase64Encoding64CharacterLineLength = 1UL << 0,
    NSDataBase64Encoding76CharacterLineLength = 1UL << 1,

    // Use zero or more of the following to specify which kind of line ending is inserted. The default line ending is CR LF.
    NSDataBase64EncodingEndLineWithCarriageReturn = 1UL << 4,
    NSDataBase64EncodingEndLineWithLineFeed = 1UL << 5,

} NS_ENUM_AVAILABLE(10_9, 7_0);

这四个选项是内部实现算法不同但是结果是一致的。
NSString *testBase64 = @"123456";
    NSData *data = [testBase64 dataUsingEncoding:NSUTF8StringEncoding];

    NSString *base64Str1 = [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
    NSString *base64Str2 = [self encode:data.bytes length:data.length];

    NSString *base64Str3 = [data base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn];
    NSString *base64Str4 = [data base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
    NSString *base64Str5 = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

    NSLog(@"the base64Str1 is %@\n", base64Str1);
    NSLog(@"the base64Str2 is %@\n", base64Str2);

    NSLog(@"the base64Str3 is %@\n", base64Str3);
    NSLog(@"the base64Str4 is %@\n", base64Str4);
    NSLog(@"the base64Str5 is %@\n", base64Str5);
//给出一个base64的c实现方式
- (NSString *)encode:(const uint8_t *)input length:(NSInteger)length {
    static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

    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] =                    table[(value >> 18) & 0x3F];
        output[index + 1] =                    table[(value >> 12) & 0x3F];
        output[index + 2] = (i + 1) < length ? table[(value >> 6)  & 0x3F] : '=';
        output[index + 3] = (i + 2) < length ? table[(value >> 0)  & 0x3F] : '=';
    }
    return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}