最近在项目中使用到了网络请求签名认证的方法,于是在网上找关于OC sha1加密
的方法,很快找到了一个大众使用的封装好的方法,以下代码便是
首先需要添加头文件
#import<CommonCrypto/CommonDigest.h>
然后直接使用下面的方法就可以了
//sha1加密方式
- (NSString *) sha1:(NSString *)input
{
const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:input.length];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, (unsigned int)data.length, digest);
NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i=0; i<CC_SHA1_DIGEST_LENGTH; i++) {
[output appendFormat:@"%02x", digest[i]];
}
return output;
}
我直接在项目中使用了这个方法,而且完美解决问题,但是,今天重点说的是这个但是,在后期的项目修改中,需要加密的字符串
里面增加了汉字(之前需要加密的字符串中无汉字),在这种情况下,上面的方法就和服务器那边的加密不一样
了(艰难的调试排除问题的过程不赘述);
最终发现的原因就是我这边生成的加密字符串和服务器
那边生成的不一样,自然就会发生错误;错误的原因就是因为加密的字符串中包含有汉字
然后是在网上查找,在<[主题:如何对中文字符串进行sha1加密][id]>这个帖子中找到了方法,现贡献给大家
[id]:http://www.cocoachina.com/bbs/read.php?tid=263440&page=e&#a
首先需要添加头文件
#import<CommonCrypto/CommonDigest.h>
然后直接使用下面的方法就可以了
//sha1加密方式
- (NSString *) sha1:(NSString *)input
{
//const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];
//NSData *data = [NSData dataWithBytes:cstr length:input.length];
NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, (unsigned int)data.length, digest);
NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];
for(int i=0; i<CC_SHA1_DIGEST_LENGTH; i++) {
[output appendFormat:@"%02x", digest[i]];
}
return output;
}
可以看出这个方法与第一个方法的区别,头两句注释掉了,用
NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding];
代替了那两句的作用;
帖子一楼bindbasic的原话是这样的
用上面的方法中文字符串转data时会造成数据丢失,
把
const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:input.length];
这两句改成
NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding];
就可以了
经实测,第二种方法的加密方式适用于纯字符串以及带有中文的字符串,推荐使用,推荐使用,推荐使用!!!(重要的事情说三遍)
备注:严格来说,sha1(安全[哈希算法])只是叫做一种算法,用于检验数据完整性
,并不能叫做加密
~感谢2楼的指点