最近做加解密遇到一个很“奇葩的问题”,解析服务端加密后的字符串 序列化 时一直报错 "json解析失败:Error Domain=NSCocoaErrorDomain Code=3840 "Garbage at end." UserInfo={NSDebugDescription=Garbage at end.}"
既然出现问题就开始找原因,根据错误分析原因,大概是 JSON 格式字符串有问题,搜了很多答案,被误导了。
本身使用 AES 解密后打印出来的 JSON 字符串是
{"UserId":"D6BA8FE3-9BBB-40F2-BC04-2CC5BCF2B353","Code":"8143502","Account":"8143502","RealName":"Robin","Spell":null,"Gender":"男","Mobile":"18621684680","Telephone":null,"Email":null,"WeChat_ID":null,"CompanyId":"31b05701-60ef-405c-87ba-af47049e3f48","CompanyName":"","DepartmentId":"52b73532-56ff-4db0-810e-9a915a5decf5","DepartmentName":"研发部","PostName":"","Enabled":"1","Remark":null}
使用 JSON 格式化也没有任何问题,但是使用下面系统自带方法一直转换失败:
- (id)dictionaryWithJsonString:(NSString *)jsonString { if (jsonString == nil) { return nil; } NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; NSError *err; id dic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&err]; if(err) { CSLog(@"json解析失败:%@",err); return nil; } CSLog(@"decryptResponse = %@", dic); return dic; }
报错信息是说 JSON 后面有垃圾后缀。跟服务端同事沟通,他们一口咬定数据没问题,让客户端解决。
推测几种可能性:
刚开始怀疑是编码问题,但是编码方式一致,排除;
后来怀疑是 服务端 设置了 " " 或者转义问题,但是对方不配合。。。只能这边进行转换,试了以下几种方式:
jsonString = [jsonString stringByReplacingOccurrencesOfString:@" " withString:@""]; jsonString = [jsonString stringByReplacingOccurrencesOfString:@" " withString:@""]; jsonString = [jsonString stringByReplacingOccurrencesOfString:@" " withString:@""]; jsonString = [jsonString stringByReplacingOccurrencesOfString:@"\" withString:@""];
后来选择把 字符串中 的 "null" 转换以下:
jsonString = [jsonString stringByReplacingOccurrencesOfString:@":null"withString:@":"""];
后来解析还是失败。。。
后来调试时发现:
后面"}"多了 " ",所以解析失败:正常的如下:
猜想应该是服务端给的数据经过客户端解密过程中出现了问题,开始查找解密算法问题:http://tool.chacuo.net/cryptaes
比对 AES 的加密模式,填充,数据块,密码,向量,输出,字符集等参数,果然是数据 填充 枚举两端不一致导致的,修改后,解析正常。
坑总结:控制台打印出来的数据自动进行了转化,看不到完整的错误数据,不方便定位问题。