Buscando el pseudo-punto fijo del MD5 en Java
2009-05-10 08:15:57
Esta es mi entrada para el reto de encontrar el punto fijo de MD5 que mencionaron el otro dia en programming.reddit. No es un código muy limpio, sino más bien una prueba de concepto para ver que tal se portaba Java... y se porta tres ordenes de magnitud más lento que las implementaciones en C tirando de OpenSSL que usa el ganador (amén de una granja de P4).
En mi maquina de casa, este código me saca unas 44.000 sumas por segundo por nucleo, muy lejos de los millones por segundo de las versiones en código nativo.
package com.saiyine.experimentos.md5;import java.security.MessageDigest;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class Sumador
{
static String hex = "01234567890abcdef";
static Random r = new Random();
static MessageDigest md;
static int contador = 0;
static long tiempo = 60;
public Sumador()
{
try
{
md = MessageDigest.getInstance( "MD5" );
} catch ( Exception e)
{
e.printStackTrace();
}
}
public String md5(String cadena)
{
String aux ="";
md.update( cadena.getBytes() );
byte[] digest = md.digest();
String moco = "";
for ( byte b : digest )
{
moco = moco +","+( b & 0xff );
String aux2 =(Integer.toHexString( b & 0xff ));
while (aux2.length()<2)
{
aux2="0"+aux2;
}
aux=aux+aux2;
}
md.reset();
return aux;
}
public static int parecido(String cadena1, String cadena2, int imprimir)
{
int aux = -1;
for (int i=0;i<32; i++)
{
cadena1 = cadena1.substring(1, 32) + cadena1.charAt(0);
int contador = 0;
for (int j=0;j<32; j++)
{
if (cadena1.charAt(j) == cadena2.charAt(j))
{
contador++;
} else
{
contador=0;
}
}
if (contador>aux)
aux=contador;
}
if (aux > imprimir)
System.out.println(cadena1+" - "+cadena2+ " "+aux);
return aux;
}
public static char hexa()
{
int i = r.nextInt(15);
return hex.charAt(i);
}
public static String azar(String cadena)
{
return hexa() + cadena.substring(0,cadena.length()-1);
}
public static void main(String[] args)
{
Sumador s = new Sumador();
Timer t = new Timer();
TimerTask task = new TimerTask()
{
public void run()
{
System.out.println((contador/tiempo)+" comprobaciones/segundo");
contador=0;
}
};
t.schedule(task, tiempo * 1000, tiempo * 1000);
String cadena1 = s.md5(""+(r.nextLong()*r.nextLong()*r.nextLong()));
String cadena2 = null;
while (true)
{
cadena1 = azar(cadena1);
cadena2 = s.md5(cadena1);
parecido(cadena1,cadena2,8);
contador++;
}
}
}