example - algoritmo hash en java
Java-Algoritmos Hash-Implementaciones más rápidas (6)
Considere BLAKE2 que es más rápido y más seguro que los hashes mencionados anteriormente.
MD5, SHA-1, SHA256 y SHA-512 son susceptibles a la extensión de longitud.
MD5 y SHA-1 son vulnerables a las colisiones.
MD5 es vulnerable a las colisiones de prefijo elegido.
SHA-3 y BLAKE2 no tienen problemas de seguridad conocidos y pueden generar compendios de duración variable.
SHA-3 es más rápido cuando se implementa en hardware; BLAKE2 es más rápido cuando se utilizan implementaciones de software.
BLAKE2b está optimizado para plataformas de 64 bits y produce compendios de cualquier tamaño entre 1 y 64 bytes.
BLAKE2s está optimizado para plataformas de 8 a 32 bits y produce compendios de cualquier tamaño entre 1 y 32 bytes.
Aquí hay puntos de referencia para AES, MD5, SHA-256 y BLAKE2b.
https://www.cryptopp.com/benchmarks.html
En el primer enlace, BLAKE2b (947 Mbits) es mucho más rápido que SHA-256 (413 Mbits) y MD5 (632 Mbits).
En el segundo enlace, AES-256 CBC (805 Mbits) y BLAKE2b (776 Mbits) tienen la misma velocidad y son más rápidos que SHA-256 (275 Mbits) y MD5 (602) Mbits.
Quiero saber cuál es la mejor y más rápida implementación de algoritmos hash para Java, especialmente MD5 y SHA-2 512 (SHA512) o 256. Quiero una función para obtener una cadena como argumento y devolver el hash como resultado. Gracias.
Editar: Esto sirve para asignar cada URL a un hash único. Dado que MD5 no es tan confiable en esta área, estoy más interesado en encontrar la mejor y más rápida implementación para los algoritmos SHA-2. Tenga en cuenta que sé que incluso SHA-2 podría producir el mismo hash para algunas URL, pero puedo vivir con eso.
Lo primero es lo primero: la velocidad está sobrevalorada. Debe tomar medidas antes de declarar que un algoritmo dado es "demasiado lento". La mayoría de las veces, la velocidad de la función hash no hace ninguna diferencia notable de todos modos. Si tiene dudas sobre la seguridad, primero seleccione una función hash que sea lo suficientemente segura y solo se preocupe por el rendimiento.
Además, quiere "cadenas" de hash. Una String
Java es, internamente, un fragmento de una matriz de valores char
que representan puntos de código Unicode (en realidad, unidades de código Unicode de 16 bits que codifican los puntos de código usando UTF-16). Una función hash toma como entrada una secuencia de bits o bytes. Por lo tanto, deberá realizar un paso de conversión, por ejemplo, str.getBytes("UTF-8")
, para obtener su cadena como un conjunto de bytes. Es probable que el paso de conversión tenga un costo no despreciable en comparación con el hash en sí mismo.
Nota: ¡cuidado con la codificación URL! En una URL, algunos bytes pueden reemplazarse con secuencias que comienzan con un signo '' %
''; esto está diseñado para admitir caracteres no imprimibles, pero también se puede usar en caracteres "estándar" (por ejemplo, reemplazando '' a
'' por '' %61
''). Esto significa que dos cadenas que son distintas (en el sentido String.equals()
) en realidad pueden representar la misma URL (en lo que respecta al procesamiento de URL). Dependiendo de su situación, esto puede o no ser un problema.
Primero debe intentar usar la API de MessageDigest
de Java con el proveedor de JCE estándar (ya instalado) (es decir, debe llamar a MessageDigest.getInstance("SHA-256")
) y analizar el resultado. Teóricamente, la JCE puede asignar la llamada a una implementación con código "nativo" (escrito en C o ensamblado), que será más rápido de lo que se puede obtener con Java.
Habiendo dicho eso...
sphlib es una implementación de código abierto de muchas funciones hash criptográficas, en C y en Java. El código se ha optimizado para la velocidad y, en la práctica, la versión de Java resulta ser más rápida que la que ofrece el estándar JRE de Sun / Oracle. Utilice este enlace en caso de que el enlace anterior falle (el servidor host principal a veces está fuera de servicio, como parece ser el caso en este momento) (advertencia: descarga de 10 MB). El archivo también contiene un informe (que se presentó en la segunda conferencia de candidatos SHA-3 en 2010) que ofrece algunas cifras de rendimiento medidas en varias plataformas, para SHA-2 y los 14 candidatos de la segunda ronda para el próximo SHA-3.
Pero realmente deberías hacer puntos de referencia en la situación. Por ejemplo, los efectos en la memoria caché L1 pueden tener un efecto drástico en el rendimiento y no pueden predecirse con precisión tomando el código de función y ejecutándolo de forma aislada.
Mira esto: muchos ejemplos de SHA / MD5
Además: del mismo hilo: Fast MD5
String hash = MD5.asHex (MD5.getHash (new File (filename)));
Otra cosa a considerar es usar MD4. No es tan seguro como MD5, pero se calcula aún más rápido. Windows hasta XP usó para almacenar e intercambiar contraseñas en MD4, entonces usamos este hash porque todavía nos permite proporcionar servicios de autenticación a esta plataforma.
Para una cadena, simplemente llame a hashCode()
porque es más económico en la sobrecarga de memoria.
De lo contrario, recomiendo este código para hash privado:
public static int hash8(String val) throws UnsupportedEncodingException {
return hash8(val.getBytes("UTF-8"));
}
public static int hash8(byte[] val) {
int h = 1, i = 0;
for (; i + 7 < val.length; i += 8) {
h = 31 * 31 * 31 * 31 * 31 * 31 * 31 * 31 * h + 31 * 31 * 31 * 31
* 31 * 31 * 31 * val[i] + 31 * 31 * 31 * 31 * 31 * 31
* val[i + 1] + 31 * 31 * 31 * 31 * 31 * val[i + 2] + 31
* 31 * 31 * 31 * val[i + 3] + 31 * 31 * 31 * val[i + 4]
+ 31 * 31 * val[i + 5] + 31 * val[i + 6] + val[i + 7];
}
for (; i + 3 < val.length; i += 4) {
h = 31 * 31 * 31 * 31 * h + 31 * 31 * 31 * val[i] + 31 * 31
* val[i + 1] + 31 * val[i + 2] + val[i + 3];
}
for (; i < val.length; i++) {
h = 31 * h + val[i];
}
return h;
}
FYI: http://lemire.me/blog/2015/10/22/faster-hashing-without-effort/
Editar: Originalmente leí la pregunta como cuál es "el algoritmo hash más rápido" y se ha aclarado que es "la implementación más rápida de cada algoritmo". Es una pregunta válida y otros han señalado implementaciones más rápidas. Sin embargo, a menos que estés mezclando grandes cantidades de datos en un corto período de tiempo, simplemente no va a importar mucho. Dudo que, por lo general, valga la pena el tiempo y la complejidad de usar algo distinto de lo que se proporciona con la JCE estándar.
En el caso de las direcciones URL, necesitaría mezclar con SHA-256 más de un millón por segundo en hardware moderno para requerir algo más rápido. No puedo imaginar que la mayoría de las aplicaciones necesiten más de mil por segundo (más de 86 millones por día), lo que significa que el tiempo total de CPU consumido será mucho menor al 1%. Entonces, incluso si tuviera un algoritmo hash infinitamente rápido, solo podría mejorar el rendimiento general en un 1% en el mejor de los casos.
Respuesta original: Obtener lo mejor y más rápido no concuerda entre sí. Los mejores hash son generalmente más lentos. Si realmente necesita velocidad y seguridad no es una gran preocupación, entonces use MD5. Si necesita la mejor seguridad, vaya con SHA-256 o incluso con SHA-512. No mencionó para qué lo usa, por lo que es difícil recomendar uno u otro. Probablemente estés más seguro yendo con SHA-256, ya que debería ser lo suficientemente rápido para la mayoría de los casos de uso en hardware moderno de todos modos. Así es cómo puedes hacerlo:
String input = "your string";
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(input.getBytes("UTF-8"));
byte[] hash = digest.digest();
Si está utilizando esto por razones de seguridad, como aplicar una contraseña, también debe agregar sal al resumen. Si quieres una cadena imprimible del hash, puedes codificarla de regreso a una cadena como hexadecimal:
static char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
StringBuilder sb = new StringBuilder(hash.length * 2);
for (byte b : hash) {
sb.append(HEX_CHARS[(b & 0xF0) >> 4]);
sb.append(HEX_CHARS[b & 0x0F]);
}
String hex = sb.toString();