2017-09-19 161 views
1

當我注意到兩個不同數據內容的散列相同時,我在NSData上使用散列函數。具有不同內容的NSData具有相同的散列

這是我的代碼:

NSDictionary * d1 = @{@"sums":@[@{@"label":@"Work", @"value":@30}, @{@"label":@"Transport", @"value":@50}, @{@"label":@"Material", @"value":@300}]}; 

    NSData * dd1 = [NSKeyedArchiver archivedDataWithRootObject:d1]; 

    NSDictionary * d2 = @{@"sums":@[@{@"label":@"Work", @"value":@30}, @{@"label":@"Transport", @"value":@50}, @{@"label":@"Material", @"value":@9}]}; 

    NSData * dd2 = [NSKeyedArchiver archivedDataWithRootObject:d2]; 

    NSInteger hashd1 = [dd1 hash]; 
    NSInteger hashd2 = [dd2 hash]; 

最後一個值是不同的,但哈希值是相同的。 我想知道如何在Objective-C中計算NSData的散列值,因爲沒有明確的文檔指導。

Printing description of hashd1: 
(NSInteger) hashd1 = 211676908 
Printing description of hashd2: 
(NSInteger) hashd2 = 211676908 
Printing description of dd2: 
<62706c69 73743030 d4010203 04050641 42582476 65727369 6f6e5824 6f626a65 63747359 24617263 68697665 72542474 6f701200 0186a0af 10110708 11121820 21222324 2a323334 3c3d3e55 246e756c 6cd3090a 0b0c0e10 574e532e 6b657973 5a4e532e 6f626a65 63747356 24636c61 7373a10d 8002a10f 80038009 5473756d 73d20a0b 1317a314 15168004 800a800d 8010d309 0a0b191c 10a21a1b 80058006 a21d1e80 07800880 09556c61 62656c55 76616c75 6554576f 726b101e d2252627 285a2463 6c617373 6e616d65 5824636c 61737365 735c4e53 44696374 696f6e61 7279a227 29584e53 4f626a65 6374d309 0a0b2b2e 10a21a1b 80058006 a22f3080 0b800c80 09595472 616e7370 6f727410 32d3090a 0b353810 a21a1b80 058006a2 393a800e 800f8009 584d6174 65726961 6c1205f5 e100d225 263f4057 4e534172 726179a2 3f295f10 0f4e534b 65796564 41726368 69766572 d1434454 726f6f74 80010008 0011001a 0023002d 00320037 004b0051 00580060 006b0072 00740076 0078007a 007c0081 0086008a 008c008e 00900092 0099009c 009e00a0 00a300a5 00a700a9 00af00b5 00ba00bc 00c100cc 00d500e2 00e500ee 00f500f8 00fa00fc 00ff0101 01030105 010f0111 0118011b 011d011f 01220124 01260128 01310136 013b0143 01460158 015b0160 00000000 00000201 00000000 00000045 00000000 00000000 00000000 00000162> 
Printing description of dd1: 
<62706c69 73743030 d4010203 04050641 42582476 65727369 6f6e5824 6f626a65 63747359 24617263 68697665 72542474 6f701200 0186a0af 10110708 11121820 21222324 2a323334 3c3d3e55 246e756c 6cd3090a 0b0c0e10 574e532e 6b657973 5a4e532e 6f626a65 63747356 24636c61 7373a10d 8002a10f 80038009 5473756d 73d20a0b 1317a314 15168004 800a800d 8010d309 0a0b191c 10a21a1b 80058006 a21d1e80 07800880 09556c61 62656c55 76616c75 6554576f 726b101e d2252627 285a2463 6c617373 6e616d65 5824636c 61737365 735c4e53 44696374 696f6e61 7279a227 29584e53 4f626a65 6374d309 0a0b2b2e 10a21a1b 80058006 a22f3080 0b800c80 09595472 616e7370 6f727410 32d3090a 0b353810 a21a1b80 058006a2 393a800e 800f8009 584d6174 65726961 6c11012c d225263f 40574e53 41727261 79a23f29 5f100f4e 534b6579 65644172 63686976 6572d143 4454726f 6f748001 00080011 001a0023 002d0032 0037004b 00510058 0060006b 00720074 00760078 007a007c 00810086 008a008c 008e0090 00920099 009c009e 00a000a3 00a500a7 00a900af 00b500ba 00bc00c1 00cc00d5 00e200e5 00ee00f5 00f800fa 00fc00ff 01010103 0105010f 01110118 011b011d 011f0122 01240126 01280131 01340139 01410144 01560159 015e0000 00000000 02010000 00000000 00450000 00000000 00000000 00000000 0160> 

甚至字節長度是不同

(lldb) po [dd1 length] 
522 

(lldb) po [dd2 length] 
524 
+0

的更多詳細信息散列值不必是唯一的。實際上,所有實例的哈希值可能相同。當然,這會使字典之類的東西效率低下很多。 'hash'的唯一要求是對於返回isEqual的'YES'的兩個對象必須是相同的:'。 – rmaddy

回答

1

它的NSData一個實現細節,但它僅使用前80個字節的數據來計算散列值,即:https://opensource.apple.com/source/CF/CF-635.21/CFData.c

static CFHashCode __CFDataHash(CFTypeRef cf) { 
    CFDataRef data = (CFDataRef)cf; 
    return CFHashBytes((uint8_t *)CFDataGetBytePtr(data), __CFMin(__CFDataLength(data), 80)); 
} 

鍵控存檔添加足夠的序言,兩個結果是相同的長度。

您可能喜歡How does NSData's implementation of the hash method work?

相關問題