Base64 原生方法 Decode 失败

最近有小伙伴问我,它的一串 e25hbWU6IuW8gOW/gyIsdHlwZTo5MSxzb3VyY2U6NH0 使用以下代码 decode 返回 nil,但是在线上 decode 就能得到正确的结果

NSData *data = [[NSData alloc]initWithBase64EncodedString:source options:0];
return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

一段代码乍看是对的,并没有什么错误,所以我们先看看 Base64 的编解码规则吧


  • Base64 组成部分
    字符组成部分包括:26个大写英文字母(A-Z),26个小写英文字母(a-z),10个数字(0-9),1个 "/",一个 "+",和起来刚好64个字符,其实还有一个作为垫字的 "=",所以总的其实是65个字符
  • Base64 编码对应的符号表
字符 编码 字符 编码 字符 编码 字符 编码 字符 编码 字符 编码 字符 编码 字符 编码
A 0 I 8 Q 16 Y 24 g 32 o 40 w 48 4 56
B 1 J 9 R 17 Z 25 h 33 p 41 x 49 5 57
C 2 K 10 S 18 a 26 i 34 q 42 y 50 6 58
D 3 L 11 T 19 b 27 j 35 r 43 z 51 7 59
E 4 M 12 U 20 c 28 k 36 s 44 0 52 8 60
F 5 N 13 V 21 d 29 l 37 t 45 1 53 9 61
G 6 O 14 W 22 e 30 m 38 u 46 2 54 + 62
H 7 P 15 X 23 f 31 n 39 v 47 3 55 / 63
  • Base64 编码规则
    每3个字符转化为4个字符(3 * 8 * N = 4 * 6 * (n + num('=') ) ),6 位满足 64 个字符表示

    1. 每 3 个字节分为 1 组,即 24 个二进制位
    2. 24 个二进制位再分为 4 组,每组 6 个二进制位
    3. 最后一组不满 6 个二进制位,在其后补 0
    4. 根据上表,每组的对应符号组合即可
    5. 1-4步骤完成后,发现组合的字符个数为n,若 n % 4 != 0 则,在末尾补充4 - (n % 4)= ,酱紫组合起来即 Base64字符
  • N % 3 == 0的情况

解码前字串: a           o          c 

对应ASCII: 01100001   01101111   01100011

每6位分割:  011000 010110 111101 100011 

10进制值:    24      22     61     35

Base64对应字符:Y      W      9      j

最后的 Base64 字符串:YW9j
  • N % 3 != 0的情况(假设等于1,2的情况类似)
解码前字串: a           o          c d

对应ASCII: 01100001   01101111   01100011 01100100

每6位分割:  011000 010110 111101 100011 011001 000000(4个0补足)

10进制值:     24      22     61     35       25    0

Base64对应字符:Y       W      9      j   |    Z     A    =    =  (2个=补足)

最后的 Base64 字符串:YW9jZA==
  • 编码
- (NSString *)base64EncodeString {
    NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
    return [data base64EncodedStringWithOptions:0];
}
  • 解码
    从上面的编码规则就可以反推解码过程了,而这其中可能拿到非标准的 Base64 字串,那就是可能没有补足 = ,所以处理过程中,需要为非标准的 Base64 字串补足 =
- (NSString *)base64DecodeString {
    NSInteger dMod = self.length % 4;
    NSString *base64Str = self;
    if (dMod) {
        base64Str = [base64Str stringByAppendingString:[@"====" substringFromIndex:dMod]];
    }
    NSData *data = [[NSData alloc]initWithBase64EncodedString:base64Str options:0];
    return [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
}

所以朋友的
e25h bWU6 IuW8 gOW/ gyIs dHlw ZTo5 MSxz b3Vy Y2U6 NH0
补足 = 即可
e25h bWU6 IuW8 gOW/ gyIs dHlw ZTo5 MSxz b3Vy Y2U6 NH0=
其实这个了解编码规则的话就能很快跟踪解决,所以仅当作一点记录吧

你可能感兴趣的:(Base64 原生方法 Decode 失败)