2016-04-14 341 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

相關問題