Anuncios Google

Programa fuerza bruta

Hola buenas.

 

Estoy elaborando como reto personal, un programa que averigue una determinada cadena comprobando caracteres uno a uno.

 

Este es el algoritmo que uso actualmente:

// Declaro la variable string de pruebas, le pongo todos los campos que voy a usar
 
string Password = "bba345678911131517192123252729313335373941434547495153555759";
 
for (int i = 0; i < Password.size(); i ++)
        Password[i] = ' ';
 
ConseguirContrasena(Password,Correcta);

bool ConseguirContrasena(string &Password,string Correcta)
{
     int longitud = 0;
     int i,j,k;
     while (1)
     {
           if (Comprobar(Password,Correcta))
                    return true;
 
           // Comprobamos cada caracter uno a uno
 
           for (i = 0; i < 255; i++) 
           {
               Password[longitud] = i;
 
               // Si coincidimos con la contraseña salimos del bucle
 
               if (Comprobar(Password,Correcta))
                    return true;
           }
 
           cout<<longitud<<" Probada";
 
           /* Sino, habra que aumentar la longitud (si la cadena probada era de un caracter */
 
           if (longitud == 0)
              longitud++;
 
           /* Si no es de un caracter, habra que modificar los caracteres anteriores      */     
 
             else
           {
               // Vamos retrocediendo hasta que lleguemos al elemento 1...
 
               for (i = longitud; i > 0;i--)
                   for (j = 0; j < 255; j++) 
                   {
                                // Cambiamos un elemento de la cadena
 
                                Password[i] = j;
 
                                 // Y volvemos a reintentar con la ultima cifra
 
                                 for (k = 0; k < 255; k++) 
                                 {
                                     Password[longitud] = k;
                                    if (Comprobar(Password,Correcta))
                                                  return true;
                                 }
                   }
 
                /* Despues de esas comprobaciones, aumentamos la longitud y volvemos al principio   */
 
               longitud++;
           }
     }             
}

 

Descarga: http://dl.dropbox.com/u/69551225/SacarContrase%C3%B1a.rar

 

Funciona bien con cadenas de 1 o 2 caracteres. Pero cuando son de 3 o más se empieza a rallar... Y acaba quedandose pillado (ten abierto el administrador de tareas antes de ejecutarlo).


Anuncios Google

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de joserc87

Se me ha colado un error.

El código anterior, una vez que encontraba la cadena, no paraba. Para arreglarlo simplemente se le añade un if y un return:

bool explora (string &Password, string Correcta, int desde, int hasta){
  if (desde>hasta){
    return (Comprobar (Password, Correcta));
  }else{
    for (int i=0; i<256; i++){
      Password [desde] = i;
      // He cambiado las dos líneas siguientes:
      if (explora (Password, Correcta, desde+1, hasta))
        return (true);
    }
  }
}

Pruebalo. Debería ir mucho más rápido.

Saludos


Be pointer my friend...

Dennis Ritchie. Padre de C y cocreador de UNIX.

R.I.P.

 

Imagen de joserc87

Longitud

En la ultima parte, donde tienes los 3 for anidados, si quieres acceder al elemento "longitud" ss Password [longitud-1]. Además, el for debería ir desde i=longitud-1 y mietras i>=0, no i>0.

Aparte de eso, lo estás haciendo mal en concepto. Fíjate que no estás explorando todas las combinaciones, sino que cambias los valores de uno en uno: primero recorres todos los valores de la primera posición, después de la segunda, etc. Sin embargo lo que tendrías que hacer es cambiar todos los valores de la última, para todos los valores de la penúltima, etc. No se si me explico. En definitiva, que para explorar todas las posibilidades lo mejor es usar una función recursiva. Sin usar recursividad seguramente también se podría hacer, pero costaría mucho más.

Imagina la función

bool explora (string &Password, string Correcta, int desde, int hasta){
  if (desde>hasta){
    return (Comprobar (Password, Correcta));
  }else{
    for (int i=0; i<256; i++){
      Password [desde] = i;
      explora (Password, Correcta, desde+1, hasta);
    }
  }
}

Que le das el rango donde tiene que hacer la combinatoria y te dice si combinando esos valores obtenemos el password. Con esa función, tan solo quedaría hacer un while de la longitud desde 1 hasta... infinito por ejemplo.

Saludos!


Be pointer my friend...

Dennis Ritchie. Padre de C y cocreador de UNIX.

R.I.P.

 

Hey! Muchas gracias.   Si te

Hey! Muchas gracias.

 

Si te he entendido, solo cambio las cifras de uno en uno, pero tambien hay otras combinaciones posibles cambiando cifras dos a dos...

 

He probado tu función y funciona perfectamente  (muy sotisficada, como se te ha ocurrido???). El unico problema es que es muyyy lenta. Para una secuencia de 3 caracteres se tira la de dios, sin embargo si uso una función con fors:

 

bool Explorar(string Password, string Correcta)
{
 
for (int i = 0; i < 255; i++)
     {
         Password[0] = i;
         if (Comprobar(Password,Correcta))
                    return true;
         for (int j = 0; j < 255; j++)
         {
             Password[1] = j;
             if (Comprobar(Password,Correcta))
                    return true;
             for (int k = 0; k < 255; k++)
             {
                 Password[2] = k;
                 if (Comprobar(Password,Correcta))
                 {
                    return true;
                 }
             }
         }
     }
     return false;
}

 

Lo saca en unos 10-15 segundos, mucho más rapido que la otra. Pero claro, no encuentro la forma de hacerla "general". Para cualquier numero de caracteres...

 

 

Imagen de joserc87

No es lo mismo.

Ten en cuenta que el código que has puesto solo vale para 3 elementos. Si no sabes el número de elementos a priori tienes que explorar todas las combinaciones de 1 elemento, de 2, etc. Osea que el número de comprobaciones serían 256+256*256+256*256*256. Tu código solo hace 256*256*256 comprobaciones. Además, mucho cuidado a la hora de comprobar los tiempos. Encontrar la cadena "aaa" es mucho más rápido que encontra la "zzz"!!


Be pointer my friend...

Dennis Ritchie. Padre de C y cocreador de UNIX.

R.I.P.

 

Imagen de Loopin

Puedes acelerar el proceso

Puedes acelerar el proceso muchísimo usando máscaras; en vez de hacer un promedio de 128 comprobaciones, sólo harías 8, es decir:

Supongamos que tenemos que encontrar el carácter  'A', que el valor ASCII asociado es el 65. Con tu algoritmo harías 65 comprobaciones erróneas (de 0 a 64), y 1 correcta. Sin embargo si representamos el valor 65 en binario con un byte, quedaría así: 0100 0001. Por tanto sólo deberás comprobar bit a bit para construir el byte (el carácter) que buscas. ¿Cómo comprobamos bit a bit? Muy sencillo, usando máscaras. Una máscara no es más que una secuencia de bits que se usa para operar con otra secuencia de bits y así extraer los bits que nos insteresan. Por ejemplo:

Máscara 1: 1000 0000 (en decimal es el valor 128)
Vamos a "multiplicarla" por nuestra aún desconocida 'A'. Para ello usaremos el operador a nivel de bits &. Éste operador devuelve el producto lógico (AND), entre cada uno de los bits de cada secuencia:

0100 0001 & 1000 0000 = 0000 0000

Por tanto, acabamos de descubrir que el primer bit de nuestro caracter desconocido es un 0 (recordemos que el operador lógico AND sólo da 1 cuando 1 AND 1, en culquier otro caso dará cero). La segunda máscara seria 0100 0000, la tercera 0010 0000 y así hasta 0000 0001. Con esto ya tendríamos el primer carácter. Por tanto como puedes ver, con tan sólo 8 comprobaciones tendrías un carácter.

Un saludo y espero haberte ayudado!

 


Interesante...   Lo he

Interesante...

 

Lo he intentado poner en practica:

void Explora_Optimizado(string &Password, string Correcta)
{
     const int Mascara1 = 256;
     const int Mascara2 = 128;
     const int Mascara3 = 64;
     const int Mascara4 = 32;
     const int Mascara5 = 16;
     const int Mascara6 = 8;
     const int Mascara7 = 4;
     const int Mascara8 = 2;
     const int Mascara9 = 1;
 
     bool Byte[9];
 
     int contador = 0;
 
     cout<<endl;
 
     while (contador < Correcta.size())
     {
               Byte[0] = Correcta[contador] & Mascara1;
               cout<<Byte[0]<<endl;
               Byte[1] = Correcta[contador] & Mascara2;
               cout<<Byte[1]<<endl;
               Byte[2] = Correcta[contador] & Mascara3;
               cout<<Byte[2]<<endl;
               Byte[3] = Correcta[contador] & Mascara4;
               cout<<Byte[3]<<endl;
               Byte[4] = Correcta[contador] & Mascara5;
               cout<<Byte[4]<<endl;
               Byte[5] = Correcta[contador] & Mascara6;
               cout<<Byte[5]<<endl;
               Byte[6] = Correcta[contador] & Mascara7;
               cout<<Byte[6]<<endl;
               Byte[7] = Correcta[contador] & Mascara8;
               cout<<Byte[7]<<endl;
               Byte[8] = Correcta[contador] & Mascara9;
               cout<<Byte[8]<<endl;
 
               cout<<endl<<Byte[0]*pow(2,9)+Byte[1]*pow(2,8)+Byte[2]*pow(2,7)+Byte[3]*pow(2,6)+Byte[4]*pow(2,5)+Byte[5]*pow(2,4)+Byte[6]*pow(2,3)+Byte[7]*pow(2,2)+Byte[8]<<endl;
 
               Password[contador] = int(Byte[0]*pow(2,8)+Byte[1]*pow(2,7)+Byte[2]*pow(2,6)+Byte[3]*pow(2,5)+Byte[4]*pow(2,4)+Byte[5]*pow(2,3)+Byte[6]*pow(2,2)+Byte[7]);
               contador++;
               cout<<"Elemento "<<contador<<" encontrado: "<<Password[contador]<<endl;
     }
}

 

Sin embargo no acaba de funcionar:

 

Imagen de Loopin

Cuidado con los tipos

Ten cuidado con los bits de cada tipo de dato. Los int se codifican con 32 bits, es decir, para codificar el 1, tendrías 00000000 00000000 00000000 00000001, cuando la tabla ASCII va desde el 0 al 255, es decir 8 bits (2^8), por lo que el tipo char viene de perlas. Además has declarado 9 máscaras, cuando solo son usables 8 de ellas, ya que el valor 256 no se puede codificar con 8 bits: 1 0000 0000.

Ten en cuenta también, que el operador &, no devuelve true o false (técnicamente sí, ya que se considera false 8 ceros, y true cualquier otro valor distinto de cero), devuelve el resultado de la "multiplicacion" bit a bit, es decir, una secuencia de bits que constituyen otro valor en binario.

Concretando, declarando 8 máscaras como char, y el array (por supuesto de 8 posiciones, del 0 al 7) bool como char tambien, y sumando los valores del array deberías obtener el valor buscado.

Un saludo!


Es que si lo declaro char si

Es que si lo declaro char si que no funciona:

 

void Explora_Optimizado(string &Password, string Correcta)
{
     const char Mascara1 = ConvertirBinario(128);
     const char Mascara2 = ConvertirBinario(64);
     const char Mascara3 = ConvertirBinario(32);
     const char Mascara4 = ConvertirBinario(16);
     const char Mascara5 = ConvertirBinario(8);
     const char Mascara6 = ConvertirBinario(4);
     const char Mascara7 = ConvertirBinario(2);
     const char Mascara8 = 1;
 
     char Byte[8];
 
     int contador = 0;
 
     cout<<endl;
 
     while (contador < Correcta.size())
     {
               Byte[0] = Correcta[contador] & Mascara1;
               cout<<Byte[0]<<endl;
               Byte[1] = Correcta[contador] & Mascara2;
               cout<<Byte[1]<<endl;
               Byte[2] = Correcta[contador] & Mascara3;
               cout<<Byte[2]<<endl;
               Byte[3] = Correcta[contador] & Mascara4;
               cout<<Byte[3]<<endl;
               Byte[4] = Correcta[contador] & Mascara5;
               cout<<Byte[4]<<endl;
               Byte[5] = Correcta[contador] & Mascara6;
               cout<<Byte[5]<<endl;
               Byte[6] = Correcta[contador] & Mascara7;
               cout<<Byte[6]<<endl;
               Byte[7] = Correcta[contador] & Mascara8;
               cout<<Byte[7]<<endl;
 
               cout<<endl<<Byte[0]*Funcion_Exponencial(8)+Byte[1]*Funcion_Exponencial(7)+Byte[2]*Funcion_Exponencial(6)+Byte[3]*Funcion_Exponencial(5)+Byte[4]*Funcion_Exponencial(4)+Byte[5]*Funcion_Exponencial(3)+Byte[6]*Funcion_Exponencial(2)+Byte[7]*Funcion_Exponencial(1)<<endl;
 
               Password[contador] = Byte[0]*Funcion_Exponencial(8)+Byte[1]*Funcion_Exponencial(7)+Byte[2]*Funcion_Exponencial(6)+Byte[3]*Funcion_Exponencial(5)+Byte[4]*Funcion_Exponencial(4)+Byte[5]*Funcion_Exponencial(3)+Byte[6]*Funcion_Exponencial(2)+Byte[7]*Funcion_Exponencial(1);
               contador++;
               cout<<"Elemento "<<contador<<" encontrado: "<<Password[contador]<<endl;
     }
}

char Funcion_Exponencial(char exponente)
{
    char contador = 0;
    char Valor= 1;
    while (contador != exponente)
    {
          Valor *= 2;
          contador++;
    }
    return Valor;
}

 

Imagen de joserc87

Un par de cosas

Prueba con unsigned char en lugar de char. Y en la penúltima línea, de la función Explora_optimizado, contador++ debe ir despues del cout, ya que sino estás accediendo al Password [] siguiente, que al principio es basura.

Sigo diciendo que eso es como hacer  Password [contador] = Correcta [contador]; de una forma más compleja y eso no es "adivinar una contraseña" puesto que ya la tienes. Es más, si esto se pudiese hacer, sería absurdo ponerle contraseña a las cosas, puesto que se podrían calcular en cuestión de segundos :P. No obstante la idea de Loopin está bien sobre todo para que aprendas a usar máscaras, que es muy util para otras cosas (ensamblador, programación de microcontroladores, sistemas operativos, etc).

PD: Arriba del todo te puse ayer el código de fuerza bruta arreglado. Ahora no debería de tardar tanto, a no ser que el password sea el 255-255-255, ya que para en cuanto que encuentra el pass xD.


Be pointer my friend...

Dennis Ritchie. Padre de C y cocreador de UNIX.

R.I.P.

 

unsigned char

unsigned char Funcion_Exponencial(unsigned char exponente)
{
    unsigned char contador = 0;
    unsigned char Valor= 1;
    while (contador != exponente)
    {
          Valor *= 2;
          contador++;
    }
    return Valor;
}
 
void Explora_Optimizado(string &Password, string Correcta)
{
     const unsigned char Mascara1 = ConvertirBinario(128);
     const unsigned char Mascara2 = ConvertirBinario(64);
     const unsigned char Mascara3 = ConvertirBinario(32);
     const unsigned char Mascara4 = ConvertirBinario(16);
     const unsigned char Mascara5 = ConvertirBinario(8);
     const unsigned char Mascara6 = ConvertirBinario(4);
     const unsigned char Mascara7 = ConvertirBinario(2);
     const unsigned char Mascara8 = 1;
 
     unsigned char Byte[8];
 
     int contador = 0;
 
     cout<<endl;
 
     while (contador < Correcta.size())
     {
               Byte[0] = Correcta[contador] & Mascara1;
               cout<<Byte[0]<<endl;
               Byte[1] = Correcta[contador] & Mascara2;
               cout<<Byte[1]<<endl;
               Byte[2] = Correcta[contador] & Mascara3;
               cout<<Byte[2]<<endl;
               Byte[3] = Correcta[contador] & Mascara4;
               cout<<Byte[3]<<endl;
               Byte[4] = Correcta[contador] & Mascara5;
               cout<<Byte[4]<<endl;
               Byte[5] = Correcta[contador] & Mascara6;
               cout<<Byte[5]<<endl;
               Byte[6] = Correcta[contador] & Mascara7;
               cout<<Byte[6]<<endl;
               Byte[7] = Correcta[contador] & Mascara8;
               cout<<Byte[7]<<endl;
 
               cout<<endl<<Byte[0]*Funcion_Exponencial(8)+Byte[1]*Funcion_Exponencial(7)+Byte[2]*Funcion_Exponencial(6)+Byte[3]*Funcion_Exponencial(5)+Byte[4]*Funcion_Exponencial(4)+Byte[5]*Funcion_Exponencial(3)+Byte[6]*Funcion_Exponencial(2)+Byte[7]*Funcion_Exponencial(1)<<endl;
 
               Password[contador] = Byte[0]*Funcion_Exponencial(8)+Byte[1]*Funcion_Exponencial(7)+Byte[2]*Funcion_Exponencial(6)+Byte[3]*Funcion_Exponencial(5)+Byte[4]*Funcion_Exponencial(4)+Byte[5]*Funcion_Exponencial(3)+Byte[6]*Funcion_Exponencial(2)+Byte[7]*Funcion_Exponencial(1);
 
               cout<<"Elemento "<<contador<<" encontrado: "<<Password[contador]<<endl;
               contador++;
 
     }
}

 

Nanay, sigue sin funcionar.

 

PD: Da igual que le ponga una "salida" a la funcion recursiva, sigue siendo increiblemente lento que si lo hago a mano con unos cuantos fors (55.4 segundos vs 26.3 segundos (secuencia de 4 caracteres))

Imagen de Loopin

No sé en que consiste la

No sé en que consiste la funcion ConvertirBinario, cuando lo tenias bien asignando el valor al char. Otra cosa es que estás operando con los valores de bytes que has obtenido de aplicar las máscaras. Es decir, la funcion evaluar potencia no debes usarla, puesto que cada bit del resultado de la máscara está en su sitio. Por tanto solo tienes que "fusionarlos" con una simple operació OR (o suma lógica, sólo da 0 cuando 0 OR 0, en caso contrario da 1): caracter = Byte[0]|Byte[1]|Byte[2]...

He escrito un miniejemplo en C:

#include <stdio.h>
#include <stdlib.h>
 
void main(){
	int j = 0;
	int i = 0;
	char *a = "hola";
	char descubierto = 0;
 
	char mascara = 1;
 
	for(j=0; j<4;j++){	//Longitud de la cadena
		for(i=0; i<8;i++){	//Numero de bits
			descubierto = descubierto | (a[j]&mascara); //Colocamos el bit en su sitio con la operacion OR
			mascara = mascara<<1;		//Hacemos un desplazamiento hacia la iz una posicion inyectando ceros. Ej: 0000 0001 << 0000 0010
		}
		printf("La letra es: %s \n", &descubierto);
		descubierto=0;		//Reinicializamos valores para la siguiente vuelta
		mascara=1;		
	}
 
 
}

Evidentemente, como bien dice joserc87, carece de sentido este tipo de algoritmos en este contexto, ya que si tuvieramos acceso a la clave buscada, simplemente hacemos clave = password, que es lo que estamos haciendo con las máscaras realmente, pero bueno aprovecharemos el ejemplo por el interés que tienes!

Un saludo!


Bueno la funcion Convertir

Bueno la funcion Convertir Binario transforma un valor decimal en un valor binario... Como hablastes de las mascaras en binario creía que había que declararlas en binario... Sí, soy estúpido xD

 

Tras eliminar la función binario y las potencias ya funciona:

 

void Explora_Optimizado(string &Password, string Correcta)
{
     const unsigned char Mascara1 = 128;
     const unsigned char Mascara2 = 64;
     const unsigned char Mascara3 = 32;
     const unsigned char Mascara4 = 16;
     const unsigned char Mascara5 = 8;
     const unsigned char Mascara6 = 4;
     const unsigned char Mascara7 = 2;
     const unsigned char Mascara8 = 1;
 
     unsigned char Byte[8];
 
     int contador = 0;
 
     cout<<endl;
 
     while (contador < Correcta.size())
     {
               Byte[0] = Correcta[contador] & Mascara1;
               cout<<Byte[0]<<endl;
               Byte[1] = Correcta[contador] & Mascara2;
               cout<<Byte[1]<<endl;
               Byte[2] = Correcta[contador] & Mascara3;
               cout<<Byte[2]<<endl;
               Byte[3] = Correcta[contador] & Mascara4;
               cout<<Byte[3]<<endl;
               Byte[4] = Correcta[contador] & Mascara5;
               cout<<Byte[4]<<endl;
               Byte[5] = Correcta[contador] & Mascara6;
               cout<<Byte[5]<<endl;
               Byte[6] = Correcta[contador] & Mascara7;
               cout<<Byte[6]<<endl;
               Byte[7] = Correcta[contador] & Mascara8;
               cout<<Byte[7]<<endl;
 
               cout<<endl<<Byte[0]+Byte[1]+Byte[2]+Byte[3]+Byte[4]+Byte[5]+Byte[6]+Byte[7]<<endl;
 
               Password[contador] = Byte[0]+Byte[1]+Byte[2]+Byte[3]+Byte[4]+Byte[5]+Byte[6]+Byte[7];
               contador++;
               cout<<"Elemento "<<contador<<" encontrado: "<<Password[contador]<<endl;
     }
}

 

Bastante rápido si señor, que lástima que no sea realista :(... Acabo de probar secuencias de 25 caracteres en menos de una décima de segundo xD. Pero bueno ya voy dando cosas nuevas, gracias : P

Imagen de Loopin

Ten en cuenta que cuando

Ten en cuenta que cuando haces:
unsigned char cadena = 128;

lo que hace el compilador es convertir el número decimal "128" en un byte (por ser un char) en una secuencia de 8 bits y además el modificador unsigned sirve para indicar que todos los valores que se van a representar en memoria no tienen signo, es decir el valor decimal minimo es el 0 (0000 0000 una vez en binario), y el máximo es el 255 (1111 1111 en binario también). Cada uno de estos números se corresponde con un carácter en el estandar ASCII, que es lo que utiliza el sistema para imprimir estos numeritos por pantalla cuando se le dicen que son caracteres.

Salu2!


Imagen de joserc87

Eso es trampa!

Eso no es fuerza bruta. Eso es como encontrar el primer caracter, luego el segundo, etc. En un caso real en el que quieras "adivinar" una contraseña no vas a poder hacer eso, ya que no vas a tener el string "correcta", solo vas a tener una función que evalúe si una contraseña es válida o no.

Saludos!


Be pointer my friend...

Dennis Ritchie. Padre de C y cocreador de UNIX.

R.I.P.

 

Imagen de Loopin

Es cierto

Jeje, tienes toda la razon, pero bueno, hay técnicas como Blind SQL Injection que permiten aplicar este tipo de algoritmos, que de alguna manera u otra agilizan la tarea. Por otra parte, explorar  todas las combinaciones secuencialmente para romper una clave de este tamaño prácticamente no tiene sentido, puesto que las claves que se generan son así de grandes por el gran coste computacional que hoy día conlleva romperla. Sería más lógico hacer uso de algoritmos probabilísticos que bueno, al fin y al cabo con "sólo" un promedio de la mitad de intentos se resolvería, (eso conociendo el tamaño de la clave...).

Me he entretenido en hacer un cálculo aproximado de cuánto se tardaría en explorar todas las combinaciones (He supuesto que el procesador, del futuro por supuesto XD, es de 10GHz, que una comprobación de la clave se realiza en una instrucción, y que cada instrucción se ejecuta en un solo ciclo de reloj):

In[12]:= dNanoS =  2^240. (*decimas de nanosegundo: t = 10^-10 seg; freq = 1/t; freq =   10^10 => 10GHz*)
 
Out[12]= 1.76685*10^72
 
In[14]:= seg = dNanoS/10^10. (* 1 seg = 10^10 décimas de nanosegundo *)
 
Out[14]= 1.76685*10^62
 
In[15]:= horas = seg/3600. (* 1 hora = 3600 segundos *)
 
Out[15]= 4.90791*10^58
 
In[16]:= dias = horas/24. (* 1 dia = 24 horas, por si hay duda :P *)
 
Out[16]= 2.04496*10^57
 
In[17]:= anos = dias/365.25 (* 1 año = 365,25 dias aprox*)
 
Out[17]= 5.5988*10^54

Si no me he equivocado con las prisas, éste sería el tiempo en años. En fin, que un par de añitos. Según wikipedia el universo tiene aproximadamente 1.37*10^10 años, comparado con los 5.59*10^54 que tardaría nuestro procesador del futuro en romper la clave (aunque bueno, teniendo en cuenta el tiempo promedio, solo tendríamos que dividir entre 2, lo cual reduce un pelín el tiempo XD). Y si ya encima desconocemos el tamaño de la clave, suponiendo que fuera de 60 caracteres, habría que hacer 2^(60!*8^60), que ya el pobre Mathematica no tiene ni memoria suficiente para hacer este cálculo (8Gb de RAM tiene mi portatil!).

Después de este curioso paréntes, y teniendo en cuenta de que las claves para encriptar suelen ser números primos muy grandes, descartamos la opción de comenzar desde el principio a buscar la clave.

Un saludo! Y espero no haber errado mucho en la explicación :P


Imagen de joserc87

Procesador cuántico

Esto ya sí que no viene al caso, pero cuando llegue la era de la computación no determinística, se podrán resolver problemas NP como este en tiempo polinomial! :). Y no es tán fantasioso puesto que ya se han creado algunos procesadores cuánticos (de pocos qbits, pero bueno). Aunque para entonces las contraseñas serán inseguras y tendremos otros sistemas de seguridad.

PD: Lo del algoritmo de fuerza bruta nunca dije que tuviese futuro, solo que es de las pocas formas de resolverlo, a no ser que uses diccionarios o cosas así. Lo único que digo es que usar la contraseña para averiguar la contraseña... es un poco ilógico no? xD

PD2: Lo que has puesto me ha recordado a un profesor que tuve. Nos preguntó una vez que orden era menor: O(n), O(n²), O(n*log(n)), O(2^100) y caimos como totos diciendo que O(2^100) era constante. "Ni de coña" dijo él xD. En fin, cosas mías.


Be pointer my friend...

Dennis Ritchie. Padre de C y cocreador de UNIX.

R.I.P.

 

Ya bueno, pero ya que

Ya bueno, pero ya que estamos. Tengo curiosidad por este metodo ^^

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.