2016-04-14 145 views
1

这里的一个基本CC_SHA256例如:CC_SHA256生成用于不同的输入相同的输出

-(void)hash:(NSData *)input 
{ 
    NSLog(@"Input is %@", [self NSDataToHex:input]); 

    NSMutableData *result = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH]; 

    CC_SHA256(CFBridgingRetain(input), input.length, result.mutableBytes); 

    NSLog(@"RESULT is %@", result); 
} 

该算法似乎是正常工作。一个小测试:

NSString* str = @"abcde"; 
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding]; 

[self hash:data]; 

NSString* str2 = @"fghijk"; 
NSData* data2 = [str2 dataUsingEncoding:NSUTF8StringEncoding]; 

[self hash:data2]; 

提供了以下的输出:

Input is 6162636465 
RESULT is <91681b5f 162cf494 238e5cac 0debbe92 c3ede9bf 4bcc7e79 845b774f b33e99f7> 
Input is 666768696A6B 
RESULT is <cccf7b6f 9acb96ae 84e9852b 1a753825 d6750555 57175c78 f86cf5fb bb3cfca7> 

现在,如果我更改第二个参数(input.length)3,我得到下面的输出:

Input is 6162636465 
RESULT is <5e83c408 f722bb9a 9f602d85 c186bcb1 ebb8fa2f 0df2cc08 5eaf2522 92b01570> 
Input is 666768696A6B 
RESULT is <5e83c408 f722bb9a 9f602d85 c186bcb1 ebb8fa2f 0df2cc08 5eaf2522 92b01570> 

这些哈希值是相同的。我期望CC_SHA256算法只是散列我的输入的前3个字符,但显然,它不会像那样工作。此外,如果我重新启动模拟器,生成的散列值与第一次不同(但仍相等)。

为什么会发生这种情况?请不要为此问题提供(明显的)解决方法。我真的很想知道算法为什么会这样。

+1

我不认为你正在传递的散列正确的论点。尝试传入'input.bytes'而不是'CFBridgingRetain(input)'。我的猜测是,如果你只是传入'input'的引用,那么你正在散列一些与'NSData'相关的内部数据,因此前端的几个字节在lanches之间是相同的和不同的。 SHA应该是确定性的,因此对于相同的输入而言,它会发生变化,这意味着您错误地使用了它。 – Jack

+0

你似乎是对的。我也认为随机性非常奇怪。你可以添加你的答案,以便我可以将其标记为正确的? – Dauntless

+0

不幸的是,在真正的应用程序中,输入字符串更长(64个字符),输入大小设置为32.两个(完全不同)字符串仍然给出相同的散列值... – Dauntless

回答

1

SHA(以及任何散列算法)应该是确定性的,因此它在不同启动之间会有所不同,这表明您可能会错误地使用它。

我的猜测是,如果你只是通过输入的参考你散列一些内部数据有关NSData,因此前几个字节是相同的,但不同之间的lanches。

查看其中一个其他问题(Sha256 in Objective-C for iPhone),以便在iOS上正确实施SHA-256。

(从上面的答案):

-(NSString*)sha256HashFor:(NSString*)input 
{ 
    const char* str = [input UTF8String]; 
    unsigned char result[CC_SHA256_DIGEST_LENGTH]; 
    CC_SHA256(str, strlen(str), result); 

    NSMutableString *ret = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2]; 
    for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++) 
    { 
     [ret appendFormat:@"%02x",result[i]]; 
    } 
    return ret; 
} 
+0

感谢回答。然而,奇怪的是,对于一个大字符串,即使该对象的前32个字节看起来是相同的,因为两个不同的长度为64的字符串都给出相同的散列 – Dauntless

相关问题