具有不同内容的NSData具有相同的散列

时间:2017-09-19 13:40:41

标签: objective-c nsdictionary 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

1 个答案:

答案 0 :(得分: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?

提供其他详细信息