JAVA——对于IdentityHashMap的理解

it2025-09-08  6

JAVA——对于IdentityHashMap的理解

场景

在实现中间相遇攻击的时候,需要对使用map存放k1加密明文得到的中间密文,中间密文作为key值,k1作为value值,然后用k2解密密文得到的中间密文去map中碰撞。 但是不同k1产生的中间密文有可能不同,所以需要解决可能出现的key值重复问题。 我目前的思路:

使用辅助list去存放重复的中间密文和k1。使用MultiMap使用IdentityHashMap(出现问题)

本文主要讨论我在这个场景下使用IdentityHashMap出现的问题,以及对于IdentityHashMap的理解。

IdentityHashMap允许key值重复的原理

简单来说,常规的Map实现类实现Map接口时,判断key值相等的方法是equals()。 而IdentityHashMap判断key值相等的方法是==。

实例1

IdentityHashMap<String, Object> map = new IdentityHashMap<String, Object>(); map.put("abc",1); map.put("abc",2); System.out.println(map); //output: {abc=2} map.clear(); String s1 = "abc"; String s2 = "abc"; map.put(s1, 1); map.put(s2, 2); System.out.println(map); //output: {abc=2}

地址值一样,IdentityHashMap会认为是相同的key,所以{“abc”,2}将{“abc”,1}覆盖了。

实例2

map.put(new String("abc"), 1); map.put(new String("abc"), 2); System.out.println(map); //output: {abc=1, abc=2}

地址值不一样,IdentityHashMap会认为是不同的key,所以{“abc”,1}和{“abc”,2}都被存入map。

使用IdentityHashMap实现中间相遇攻击

public static ArrayList<K> attack(String m, String c) { IdentityHashMap<String, String> tmpMap = new IdentityHashMap<>(); ArrayList<K> list = new ArrayList<>(); for(int i = 0; i < 65536; i++) { String k1 = DECtoBIN(i); //十进制转二进制字符串 String mid = DES(m, k1); //加密算法 tmpMap.put(mid, k1); //将k1加密明文得到的中间状态存入map } for(int i = 0; i < 65536; i++) { String k2 = DECtoBIN(i); //十进制转二进制字符串 String mid = reDES(c, k2); //解密算法 if(tmpMap.containsKey(mid)) { //碰撞,这个地方出现问题 for(Map.Entry<String, String> entry : tmpMap.entrySet()) { if(entry.getKey().equals(mid)) { list.add(new K(entry.getValue(), k2)); } } } } return list; }

出现的问题以及对问题的分析

问题

碰撞的时候出现问题

if(tmpMap.containsKey(mid))

问题分析

上文提到,IdentityHashMap判断key值是否相等的方法是==,对于对象而言也就是判断地址值是否相等。

碰撞的时候使用的中间状态对象是个新对象,地址值不同,所以碰撞会失败。

想要解决问题,我的思路是要找到原来的地址值,但是现在还没有办法实现。

对于IdentityHashMap的理解

很多资料说IdentityHashMap可以存放相同的key,我个人觉得这样的说法比较具有误导性。

IdentityHashMap在实现Map接口时,罕见地违反了常规,没有使用equals(),而是使用==去判断两个key值是否相等。

所以虽然有时候看起来IdentityHashMap可以存放“相同的key”,但对IdentityHashMap而言,这对看起来相同的key本质上还是不同的key。

在大部分需要碰撞key值的场景中,需要的都是对象相等,使用equals()来判断key值是否相等显然比用==来判断key值是否相等合理。

综上所述,我认为IdentityHashMap仅适用于一些需要引用相等的特殊场景。

最新回复(0)