Como siempre en seguridad, ¿contra qué amenaza intenta protegerse?
Parece que de la pregunta le preocupa la disponibilidad. Normalmente, una tabla hash tendrá un rendimiento limitado de O (1) para operaciones simples, pero se degradará al peor de los casos de O (n). (Consulte Pautas de codificación segura para Java SE ). Diga, ¿un servidor web? use recursos desproporcionados al tamaño de una solicitud en el peor de los casos maliciosamente diseñada. El artículo vinculado en la questio trata sobre la serialización de Java, que es un agujero diferente (y realmente no protege la disponibilidad).
Todo depende de la implementación.
Hace aproximadamente una década, la implementación de Sun de HashMap
generalmente solo usaba un módulo de lo que fuera de Object.hashCode
. Ver por ejemplo, la definición de String.hashCode
. Para String
es trivial generar un texto diferente con el mismo hash. Dale a un antiguo HashMap
un montón de claves con el mismo hash, solo usarán un cubo, y el rendimiento será terrible.
Más tarde, la implementación de Sun mezcló el valor hash antes de tomar el módulo. Sin embargo, si el hash era el mismo para empezar, seguirá siendo el mismo.
TreeMap
resuelve los problemas, pero el rendimiento benigno del caso no es el mejor, aunque ha mejorado.
Más recientemente, para aplacar a aquellos que no saben cómo funcionan las tablas hash, OpenJDK utilizó variantes de MurmurHash, con una semilla aleatoria por instancia, para String
cuando hay muchas colisiones. Esto reemplaza a String.hashCode
- simplemente agregando el mismo número a un hash fijo no alterará las colisiones. Aunque técnicamente "no criptográfico", es supuestamente difícil generar colisiones sin conocer la semilla secreta. Siempre hay canales laterales.
Ahora reemplazando MurmurHash, es el algoritmo obvio de usar un árbol en lugar de una lista lineal para grupos cuando ha habido muchas colisiones. Como HashMap
nunca fue diseñado para esto, es un hack escandaloso, pero es un hack en el que aparece la biblioteca con olor a rosas, incluso cuando se abusa (en su mayoría). El algoritmo alternativo solo entra en uso cuando hay muchas colisiones (como con Murmur) y solo en los casos en que cada clave parece implementar Comparable
compatible con el tipo.