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=
其实这个了解编码规则的话就能很快跟踪解决,所以仅当作一点记录吧

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,539评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,911评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,337评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,723评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,795评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,762评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,742评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,508评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,954评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,247评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,404评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,104评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,736评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,352评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,557评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,371评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,292评论 2 352