iOS: [NSString hash]出现同样的hash值问题

当字符串长度不超过96个字符、长度不同且特定条件不满足时,使用`[NSString hash]`可能会得到相同的值。为解决此问题,可以采用SHA1哈希方法,确保对整个字符串生成唯一指纹。本文提供了Objective-C实现SHA1哈希的代码示例,并提及了获取MD5和SHA1的方法。

问题原因:

At least there are special circumstances for which this unreliability kicks in.

Comparing [a hash] and [b hash] of two different NSString is safe when:

  • the strings' length is shorter or equal to 96 characters.
  • [a length] is different to [b length].
  • the concatinated first, middle, and last 32 characters of a differ to the concatinated components of b.

Otherwise every difference between the first and the middle 32 chars, as well as every difference between the middle and the last 32 characters, are not used while producing the [NSString hash] value.

解决方法:

For my case, the solution was pretty easy. I made use of a sha1 hash, which produced 
a fingerprint from the whole string instead of pieces only. I got mine inspired by 
the SHA1 method of Saurabh Sharma

lang:objc SHA1

  • (NSString *)sha1 { NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding]; uint8t digest[CCSHA1DIGESTLENGTH];

    CC_SHA1(data.bytes, data.length, digest);

    NSMutableString *output = [NSMutableString stringWithCapacity:CCSHA1DIGEST_LENGTH * 2];

    for (int i = 0; i < CCSHA1DIGEST_LENGTH; i++) { [output appendFormat:@"%02x", digest[i]]; }

    return output; }

The SHA1 was for the name of a cached file, generated by giving the complete URL of the resource to be cached. Works perfect. I already filed a pull request for

http://www.makebetterthings.com/iphone/how-to-get-md5-and-sha1-in-objective-c-ios-sdk/

PS:

How to get md5 and SHA1 in objective c (iOS sdk)

Calculating the md5 and sha1 hash in iOS sdk is pretty simple -

Step 1 – The very first thing you need to do is import CommonCrypto’s CommonDigest.h

#import <CommonCrypto/CommonDigest.h>

Step 2 – Here is the real code for calculating SHA1 and MD5 hash -

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, 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;

}

MD5 -

- (NSString *) md5:(NSString *) input
{
 const char *cStr = [input UTF8String];
 unsigned char digest[16];
 CC_MD5( cStr, strlen(cStr), digest ); // This is the md5 call

 NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];

 for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
 [output appendFormat:@"%02x", digest[i]];

 return  output;

}

Hope it will help someone!!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小涵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值