Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 20-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Crear bucle de fuerza bruta con rango de caracteres

Hola amigos, estoy probando a ver si consigo que esta funcion funcione correctamente. Ya lo hace pero no me convence ya que uso algo de trampa para que funcione jejeje.
Lo que quiero es que cree una cadena de caracteres usando un rango y que vaya avanzando hasta crear todas las combinaciones posibles y que vaya comparando con otra cadena para ver si son iguales. Esto es lo que tengo hecho:
Código PHP:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   
AnsiString Rango "0123456789ABCDEF©"//El ultimo caracter no sirve y es simplemente un caracter de control para saber cuando se llega al final e incrementar
   
AnsiString cadena "FAAF"//Cadena hexa a buscar. No puede ser mayor que "FFFFFFFF"
   
AnsiString Salida;
   
bool retval;
   
bool error=false//bandera para la verificacion de la cadena
   
double tiempoInicialtiempoFinal;

   
//Podemos asegurarnos de que el valor de cadena es hexa antes de seguir para evitar problemas
   
for(int i 1i<=cadena.Length() && error != truei++)
   {
      if( (
cadena[i] < '0' || cadena[i] > '9') &&
          (
cadena[i] < 'A' || cadena[i] > 'F') &&
          (
cadena[i] < 'a' || cadena[i] > 'f') )
      {
         
ShowMessage(AnsiString().sprintf("La cadena %s no es hexadecimal"cadena));
         
error true;
      }
   }

   
//Tambien deberiamos asegurarnos de que el largo de la cadena no exceda del maximo
   
if(cadena.Length() > 8)
   {
      
ShowMessage(AnsiString().sprintf("El largo de cadena excede del largo máximo.\nLargo actual: %d\nLargo máximo permitido: %d"cadena.Length(),8));
      
error true;
   }

   if(
error != true//Si no se produjo ningun error seguimos adelante
   
{
      
Form1->WindowState wsMinimized//Minimizamos el form para que el usuario no pueda pulsar el boton ni nada

      
tiempoInicial GetTickCount(); //Obtenemos el tiempo de entrada

      
retval FuerzaBruta(cadena, &SalidaRango);

      if(
retval == false){ //Si no se encontró avisamos
         
ShowMessage("No se encontró el valor");
      }else{
         
tiempoFinal GetTickCount(); //obtenemos el tiempo de salida

         
ShowMessageAnsiString().sprintf"Valor hexadecimal: %s\n"
                                            "Se han tardado %s segundos en encontrarlo."
,
                                            
SalidaFormatFloat("0.000",(tiempoFinal tiempoInicial) /1000)));
      }
      
Form1->WindowState wsNormal//volvemos a restaurar el form
   
}
}
//---------------------------------------------------------------------------

bool FuerzaBruta(AnsiString SerialAnsiString *SalidaAnsiString Rango)
{
   
int xpos 1;
   
AnsiString Mascara "";
   
char valorInicialvalorFinal//Es el valor inicial y final de caracter a buscar
   
bool fin falsesig falseretval false;

   
//Asignamos el rango de busqueda
   
valorInicial Rango[1];
   
valorFinal Rango[Rango.Length()];

   
//Rellenamos la mascara a usar para dar formato
   
for(int z=1<= Serial.Length(); z++)
      
Mascara += valorInicial;

   
//Pongo x con el largo de la cadena de la mascara ya que esta será la que recorra toda la mascara y empieza desde el ultimo caracter
   
Mascara.Length();

   
//Bucle de fuerza bruta
   
do{
      
//Si obtuvimos un serial bueno
      
if(Mascara == Serial)
      {
         *
Salida Mascara//Guardamos el serial en el buffer de salida
         
retval true//Indicamos que encontramos la cadena
         
fin true//Indicamos que debemos salir ya
      
}else{

         
//Incrementamos el caracter
         
Mascara[x] = Rango[++pos];

         
//Mientras que el valor del caracter sea igual que el valor del caracter usado como tope...
         
while(Mascara[x] == valorFinal && fin != true)
         {
            
//Si no es el primer caracter
            
if(!= 1)
            {
               
//Inicializamos el caracter con el primer valor válido
               
Mascara[x] = valorInicial;

               
//Retrocedemos una posicion en la cadena
               
x--;

               
pos Rango.Pos(Mascara[x]); //Buscamos la posicion del caracter en el rango
               
Mascara[x] = Rango[pos+1]; //Incrementamos el valor del caracter
               
sig=true//Indicamos que se ha reajustado la cadena porque llegamos al final en un caracter
            
}
            else
            {
               
//Y si llegamos al valor máximo en el primer carácter
               //Forzamos la salida del procedimiento
               
fin true;
            }
         }

         
//Si algun caracter llegó hasta el final y se tuvo que reajustar todo...
         
if(sig==true)
         {
            
x=Mascara.Length(); //volvemos a colocar el indice al final de la cadena
            
sig=false//Volvemos a poner a false el flag que nos indica que se llego al final en un caracter
            
pos=1//Colocamos el indice del rango apuntando al primer caracter del rango
         
}
      }
   }while(
fin == false);

   return 
retval;
}
//--------------------------------------------------------------------------- 
El tema es que para hacer que funcione tengo que poner un caracter mas en el rango, el cual uso para saber si llego al final del rango valido o no y me gustaria no tener que usar un caracter mas, simplemente los que yo quiera que use para la generacion. No se si me explico bien.
¿podeis ayudarme?
Gracias por adelantado.
Responder Con Cita
  #2  
Antiguo 20-10-2014
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Usa strlen ().
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #3  
Antiguo 20-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Bueno, lo he solucionado asi pero no me termina de convencer porque entra dos veces en el while que reajusta la cadena y eso en un algoritmo de fuerza bruta no es bueno:

Código PHP:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   
AnsiString Rango "0123456789ABCDEF"//El ultimo caracter no sirve y es simplemente un caracter de control para saber cuando se llega al final e incrementar
   
AnsiString cadena "F1ACA"//Cadena hexa a buscar. No puede ser mayor que "FFFFFFFF"
   
AnsiString Salida;
   
bool retval;
   
bool error=false//bandera para la verificacion de la cadena
   
double tiempoInicialtiempoFinal;

   
//Podemos asegurarnos de que el valor de cadena es hexa antes de seguir para evitar problemas
   
for(int i 1i<=cadena.Length() && error != truei++)
   {
      if( (
cadena[i] < '0' || cadena[i] > '9') &&
          (
cadena[i] < 'A' || cadena[i] > 'F') &&
          (
cadena[i] < 'a' || cadena[i] > 'f') )
      {
         
ShowMessage(AnsiString().sprintf("La cadena %s no es hexadecimal"cadena));
         
error true;
      }
   }

   
//Tambien deberiamos asegurarnos de que el largo de la cadena no exceda del maximo
   
if(cadena.Length() > 8)
   {
      
ShowMessage(AnsiString().sprintf("El largo de cadena excede del largo máximo.\nLargo actual: %d\nLargo máximo permitido: %d"cadena.Length(),8));
      
error true;
   }

   if(
error != true//Si no se produjo ningun error seguimos adelante
   
{
      
Form1->WindowState wsMinimized//Minimizamos el form para que el usuario no pueda pulsar el boton ni nada

      
tiempoInicial GetTickCount(); //Obtenemos el tiempo de entrada

      
retval FuerzaBruta(cadena, &SalidaRango);

      if(
retval == false){ //Si no se encontró avisamos
         
ShowMessage("No se encontró el valor");
      }else{
         
tiempoFinal GetTickCount(); //obtenemos el tiempo de salida

         
ShowMessageAnsiString().sprintf"Valor hexadecimal: %s\n"
                                            "Se han tardado %s segundos en encontrarlo."
,
                                            
SalidaFormatFloat("0.000",(tiempoFinal tiempoInicial) /1000)));
      }
      
Form1->WindowState wsNormal//volvemos a restaurar el form
   
}
}
//---------------------------------------------------------------------------

bool FuerzaBruta(AnsiString SerialAnsiString *SalidaAnsiString Rango)
{
   
int xpos 1;
   
AnsiString Mascara "";
   
char valorInicialvalorFinal//Es el valor inicial y final de caracter a buscar
   
bool fin falsesig falseretval false;

   
//Asignamos el rango de busqueda
   
valorInicial Rango[1];
   
valorFinal Rango[Rango.Length()];

   
//Rellenamos la mascara a usar para dar formato
   
for(int z=1<= Serial.Length(); z++)
      
Mascara += valorInicial;

   
//Pongo x con el largo de la cadena de la mascara ya que esta será la que recorra toda la mascara y empieza desde el ultimo caracter
   
Mascara.Length();

   
//Bucle de fuerza bruta
   
do{
      
//Si obtuvimos un serial bueno
      
if(Mascara == Serial)
      {
         *
Salida Mascara//Guardamos el serial en el buffer de salida
         
retval true//Indicamos que encontramos la cadena
         
fin true//Indicamos que debemos salir ya
      
}else{

         if(++
pos <= Rango.Length())
         {
            
//Incrementamos el caracter
            
Mascara[x] = Rango[pos];
         }

         
//Mientras que el valor del caracter sea igual que el valor del caracter usado como tope...
         
while(pos Rango.Length() && fin != true)
         {
            
//Si no es el primer caracter
            
if(!= 1)
            {
               
//Inicializamos el caracter con el primer valor válido
               
Mascara[x] = valorInicial;

               
//Retrocedemos una posicion en la cadena
               
x--;

               
pos Rango.Pos(Mascara[x]); //Buscamos la posicion del caracter en el rango
               
if(pos == Rango.Length())
               {
                  
Mascara[x]=valorInicial;
               }else{
                  
Mascara[x] = Rango[pos+1]; //Incrementamos el valor del caracter
                  
sig=true//Indicamos que se ha reajustado la cadena porque llegamos al final en un caracter
               
}
            }
            else
            {
               
//Y si llegamos al valor máximo en el primer carácter
               //Forzamos la salida del procedimiento
               
fin true;
            }
         }

         
//Si algun caracter llegó hasta el final y se tuvo que reajustar todo...
         
if(sig==true)
         {
            
x=Mascara.Length(); //volvemos a colocar el indice al final de la cadena
            
sig=false//Volvemos a poner a false el flag que nos indica que se llego al final en un caracter
            
pos=1//Colocamos el indice del rango apuntando al primer caracter del rango
         
}
      }
   }while(
fin == false);

   return 
retval;
}
//--------------------------------------------------------------------------- 
¿Alguna solucion mejor?
Ñuño strlen no me soluciona nada ya que uso AnsiString y uso Length() que es lo mismo.
Responder Con Cita
  #4  
Antiguo 20-10-2014
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Había leído mal. :/
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #5  
Antiguo 21-10-2014
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.195
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Fíjate en este código usando char* y funciones C:

Código PHP:
bool FuerzaBruta(charSerialcharSalidacharRango)
{
  
int L strlen(Serial);
  
int R strlen(Rango);
  
int n;
  for(
n=0n<Ln++) Salida[n] = *Rango;
  
Salida[n] = 0;
  for(
n=0n<Ln++){
    for(
int r=0r<Rr++){
      
Salida[n] = Rango[r];
      if(
Salida[n] == Serial[n]) break;
    }
  }
}
//--------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
   
charRango "0123456789ABCDEF";
   
charSerial "FAAF"//Cadena hexa a buscar. No puede ser mayor que "FFFFFFFF"
   
charSalida = new char[strlen(Serial)+1];

   
bool retval;
   
bool error=false//bandera para la verificacion de la cadena
   
double tiempoInicialtiempoFinal;

   
//Podemos asegurarnos de que el valor de cadena es hexa antes de seguir para evitar problemas
   
for(int i 0strlen(Serial) && error != truei++)
   {
      if(!
isalnum(Serial[i])){
         
ShowMessage(AnsiString().sprintf("La cadena %s no es hexadecimal"Serial));
         
error true;
      }
   }

   
//Tambien deberiamos asegurarnos de que el largo de la cadena no exceda del maximo
   
if(strlen(Serial) > 8)
   {
      
ShowMessage(AnsiString().sprintf("El largo de cadena excede del largo máximo.\nLargo actual: %d\nLargo máximo permitido: %d"strlen(Serial),8));
      
error true;
   }

   if(
error != true//Si no se produjo ningun error seguimos adelante
   
{
      
Form1->WindowState wsMinimized//Minimizamos el form para que el usuario no pueda pulsar el boton ni nada

      
tiempoInicial GetTickCount(); //Obtenemos el tiempo de entrada

      
retval FuerzaBruta(SerialSalidaRango);

      if(
retval == false){ //Si no se encontró avisamos
         
ShowMessage("No se encontró el valor");
      }else{
         
tiempoFinal GetTickCount(); //obtenemos el tiempo de salida

         
ShowMessageAnsiString().sprintf"Valor hexadecimal: %s\n"
                                            "Se han tardado %s segundos en encontrarlo."
,
                                            
SalidaFormatFloat("0.000",(tiempoFinal tiempoInicial) /1000)));
      }
      
Form1->WindowState wsNormal//volvemos a restaurar el form
   
}
   
delete [] Salida;


Saludos.
Responder Con Cita
  #6  
Antiguo 21-10-2014
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
SI necesitas hacer una permutacion de caracteres encontre esto googleando:

http://www.geeksforgeeks.org/write-a...-given-string/

No es tan compacto como en python, pero me parecio muy simple de seguir (si quieres un ejemplo en python con lo cual testear rapido):

http://stackoverflow.com/questions/8...ring-in-python
__________________
El malabarista.
Responder Con Cita
  #7  
Antiguo 21-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Escafandra lo que tu me pones no es lo que deseaba hacer, tu lo que haces es comparar caracter por caracter y pasas al siguiente cuando estos coinciden.
mamcx tampoco queria permutar los caracteres aunque me ha parecido muy interesante ya que hace mucho intenté crear una aplicacion para resolver el juego televisivo de cifras y letras donde te daban 9 letras entre consonantes y vocales y tenias que sacar la palabra mas larga posible. Estuve viendo el tema de la permutacion pero un amigo me dijo que lo estaba planteando mal y que mejor que eso era, por ejemplo, supongamos que las 9 letras son ASTMAEALO, pues lo que el me planteó fue crear un diccionario y luego ordenar todas las letras de cada palabra por su orden alfabetico, o sea, si fuese ALA pues AAL, AVION pues AINOV, y asi con todas, luego hacer lo mismo con las letras que nos han dado quedando como AAAELMOST y buscar en el diccionario todas sus posibilidades como AAAELMOST, AAELMOST, AELMOST, ELMOST, y asi con todas las convinaciones posibles. Creo recordar que era así y fue muy eficaz.
Ahora a lo que ibamos, ya lo he solucionado y era mas sencillo de lo que parecia y solo me faltó ajustar alguna cosilla. Asi quedó:
Código PHP:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   
AnsiString Rango "0123456789ABCDEF"//El ultimo caracter no sirve y es simplemente un caracter de control para saber cuando se llega al final e incrementar
   
AnsiString cadena "F1ACA"//Cadena hexa a buscar. No puede ser mayor que "FFFFFFFF"
   
AnsiString Salida;
   
bool retval;
   
bool error=false//bandera para la verificacion de la cadena
   
double tiempoInicialtiempoFinal;

   
//Podemos asegurarnos de que el valor de cadena es hexa antes de seguir para evitar problemas
   
for(int i 1i<=cadena.Length() && error != truei++)
   {
      if( (
cadena[i] < '0' || cadena[i] > '9') &&
          (
cadena[i] < 'A' || cadena[i] > 'F') &&
          (
cadena[i] < 'a' || cadena[i] > 'f') )
      {
         
ShowMessage(AnsiString().sprintf("La cadena %s no es hexadecimal"cadena));
         
error true;
      }
   }

   
//Tambien deberiamos asegurarnos de que el largo de la cadena no exceda del maximo
   
if(cadena.Length() > 8)
   {
      
ShowMessage(AnsiString().sprintf("El largo de cadena excede del largo máximo.\nLargo actual: %d\nLargo máximo permitido: %d"cadena.Length(),8));
      
error true;
   }

   if(
error != true//Si no se produjo ningun error seguimos adelante
   
{
      
Form1->WindowState wsMinimized//Minimizamos el form para que el usuario no pueda pulsar el boton ni nada

      
tiempoInicial GetTickCount(); //Obtenemos el tiempo de entrada

      
retval FuerzaBruta(cadena, &SalidaRango);

      if(
retval == false){ //Si no se encontró avisamos
         
ShowMessage("No se encontró el valor");
      }else{
         
tiempoFinal GetTickCount(); //obtenemos el tiempo de salida

         
ShowMessageAnsiString().sprintf"Valor hexadecimal: %s\n"
                                            "Se han tardado %s segundos en encontrarlo."
,
                                            
SalidaFormatFloat("0.000",(tiempoFinal tiempoInicial) /1000)));
      }
      
Form1->WindowState wsNormal//volvemos a restaurar el form
   
}
}
//---------------------------------------------------------------------------

bool FuerzaBruta(AnsiString SerialAnsiString *SalidaAnsiString Rango)
{
   
int xpos 1;
   
AnsiString Mascara "";
   
bool fin falsesig falseretval false;

   
//Rellenamos la mascara a usar para dar formato
   
for(int z=1<= Serial.Length(); z++)
      
Mascara += Rango[1];

   
//Pongo x con el largo de la cadena de la mascara ya que esta será la que recorra toda la mascara y empieza desde el ultimo caracter
   
Mascara.Length();

   
//Bucle de fuerza bruta
   
do{
      
//Si obtuvimos un serial bueno
      
if(Mascara == Serial)
      {
         *
Salida Mascara//Guardamos el serial en el buffer de salida
         
retval true//Indicamos que encontramos la cadena
         
fin true//Indicamos que debemos salir ya
      
}else{

         if(++
pos <= Rango.Length()) //Si incrementamos la posicion en el rango y esta no desborda al rango...
         
{
            
//Incrementamos el caracter
            
Mascara[x] = Rango[pos];
         }

         
//Mientras que el valor del caracter sea igual que el valor del caracter usado como tope y no hayamos llegado al fin...
         
while(pos Rango.Length() && fin != true)
         {
            
//Si no es el primer caracter
            
if(!= 1)
            {
               
//Inicializamos el caracter con el primer valor del rango
               
Mascara[x] = Rango[1];

               
//Retrocedemos una posicion en la cadena
               
x--;

               
pos Rango.Pos(Mascara[x]); //Buscamos la posicion del caracter en el rango
               
pos++; //Incrementamos en 1 esa posición para actualizar el siguiente caracter de la máscara

               
if(pos <= Rango.Length()) //Si la posición no desborda al rango...
               
{
                  
Mascara[x] = Rango[pos]; //Actualizamos el valor del caracter
                  
sig=true//Indicamos que se ha reajustado la cadena porque llegamos al final en un caracter
               
}
            }
            else
            {
               
//Y si llegamos al valor máximo en el primer carácter
               //Forzamos la salida del procedimiento
               
fin true;
            }
         }

         
//Si algun caracter llegó hasta el final y se tuvo que reajustar todo...
         
if(sig==true)
         {
            
x=Mascara.Length(); //volvemos a colocar el indice al final de la cadena
            
sig=false//Volvemos a poner a false el flag que nos indica que se llego al final en un caracter
            
pos=1//Colocamos el indice del rango apuntando al primer caracter del rango
         
}
      }
   }while(
fin == false); //Saldremos solo cuando encontremos la cadena buscada o cuando hayamos llegado al final

   
return retval//Retornamos true si se ha encontrado la cadena y false si no se ha encontrado
}
//--------------------------------------------------------------------------- 
La verdad es que pienso que usando quizas recursibidad seria mas sencillo de plantear pero no fui capaz de dar con la tecla para hacerlo ya que la recursibidad se me atraganta y me cuesta muchisimo de entenderla. Ademas no se si seria sostenible ya que entendí que a mas recursividad, mas recursos del sistema usa ¿es asi?

Última edición por aguml fecha: 21-10-2014 a las 11:01:03.
Responder Con Cita
  #8  
Antiguo 21-10-2014
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Cita:
Empezado por aguml Ver Mensaje
La verdad es que pienso que usando quizas recursibidad seria mas sencillo de plantear pero no fui capaz de dar con la tecla para hacerlo ya que la recursibidad se me atraganta y me cuesta muchisimo de entenderla. Ademas no se si seria sostenible ya que entendí que a mas recursividad, mas recursos del sistema usa ¿es asi?
Por lo que estoy leyendo (y si ahora leí bien) es posible que con recursividad sea la mejor opción. O mejor aún, usar la máxima de Cayo Julio César "DIVIDE ET VINCERE". Haz un procedimiento simple para las distintas fases del proceso (esta compara cadenas, esta compara una cadena con esta lista de cadenas, esta construye la siguiente de la secuencia, etc.).

Y eso de que la recursividad usa más recursos no siempre es cierto. Depende de muchos factores. Por ejemplo, el algoritmo de ordenación de burbuja sí puede resultar más pesada usando recursión, pero la QuickSort suele necesitar menos memoria con recursión que sin ella.
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #9  
Antiguo 21-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Bueno pues como solo es una prueba lo voy a dejar asi aunque me sigue interesando el tema de hacerla recursiva para hacer pruebas con ella. De momento he hecho 3 versiones diferentes y las tres funcionan perfectamente pero con tiempos diferentes:

Imagen de rendimientos aquí

Y subo los tres modos que he usado para que opinen y asi aprendemos un poquito mas los que no sabemos tanto como algunos maestros de este foro (No nombro a ninguno para que no se me enfade nadie).

PD: En la prueba 1 solo se puede usar hasta el valor máximo de un entero sin signo mientras que en los otros dos se puede usar sin limites aunque ya sabemos que la fuerza bruta tiene un problema y es que a mayor largo del serial, mas tiempo se necesitaria y podria llegar a ser casi infinito en el tiempo .
Archivos Adjuntos
Tipo de Archivo: rar prueba fuerza bruta 1.rar (4,6 KB, 2 visitas)
Tipo de Archivo: rar prueba fuerza bruta 2.rar (5,2 KB, 1 visitas)
Tipo de Archivo: rar prueba fuerza bruta 3.rar (5,2 KB, 2 visitas)
Responder Con Cita
  #10  
Antiguo 21-10-2014
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Cita:
Empezado por aguml Ver Mensaje
Ademas no se si seria sostenible ya que entendí que a mas recursividad, mas recursos del sistema usa ¿es asi?
En lenguajes sin Tail call optimization -que son la mayoria- es problematico usar recursividad porque se puede generar un Stack Overflow ya que la mayoria de los lenguajes se estructuran como maquinas de stack con # limitado de recursiones.

Osea, que a menos que sepas con certeza que lo que haces con recursividad se puede "cortar" a tiempo, es mejor usar un metodo diferente. TODOS los algoritmos recursivos se pueden volver no recursivos.
----
Sigo sin entender que rayos quieres. Para que estas haciendo esto? Podrias dar una lista de datos de ejemplo con ejemplos de valores validos y valores invalidos?
__________________
El malabarista.
Responder Con Cita
  #11  
Antiguo 22-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
pues solo queria ver como hacer eso, era solo por ver como era, no es por algo en concreto. Yo por ejemplo en estos ejemplos a la cadena valida solo le he sumado 10 a cada caracter y esa es la cadena que busco despues en el bucle de fuerza bruta haciendo la misma operacion con cada cadena posible y comparando con la válida y si coincide ya tendrias el serial bueno. Ahora mismo no lo necesito para nada pero para seriales pequeños la fuerza bruta es muy válida.
Responder Con Cita
  #12  
Antiguo 22-10-2014
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Bueno, el primer paso es tener claro cual es el problema. Y no veo claro cual es.
__________________
El malabarista.
Responder Con Cita
  #13  
Antiguo 22-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
bueno, a ver si ahora lo entiendes, imagina una aplicacion que para acceder a ella necesitas una clave de 8 caracteres y solo admite caracteres hexadecimales. Entonces examinas y ves que coge el serial que introduces y le aplica un md5 y al resultado lo compara con un md5 que tiene guardado. Solo si son iguales podras acceder a la aplicacion y no puedes modificar el binario. Como sabras, el md5 es irreversible asi que la unica solucion seria crear un bucle de fuerza bruta que sea capaz de probar todos los seriales posibles aplicando el md5 a cada uno y comparar el resultado con el md5 bueno. Esa seria la idea y es util cuando no es muy largo es serial. Ahora con las nuevas gpu y cuda la cosa es mucho mas rapida con lo que se podrian atacar a claves mas largas. Otra opcion es atacar a la clave desde varios ordenadores repartiendo el trabajo, por ejemplo, si son 16 ordenadores podria uno atacar desde 000000000 a 0FFFFFFFF, otro desde 111111111 hasta 1FFFFFFFF y asi el resto disminuyendo los tiempos. Habia una aplicacion que se usa para eso en cuda y que era configurable pero mi gpu no soporta cuda asi que no pude probarla.
Responder Con Cita
  #14  
Antiguo 22-10-2014
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Ah! Estas intentando hacer un "Ataque de arcoiris".

Eso se hace con un https://en.wikipedia.org/wiki/Rainbow_table.

Una explicacion del algoritmo:

http://crypto.stackexchange.com/ques...ble-generation

Como notas, se genera una *tabla*. Si eres listo, no la computas cada vez, sino que la pre-generas. Como pa' rematar sabes *exactamente* de donde hasta adonde va el rango de ataque pan comido. Asi que guardas la tabla pregenerada (ej: En sqlite o un motor sql o lo que sea), y solo tienes que hacer un "SELECT Clave FROM Rainbow WHERE Hash=EsteHash). Eso debe salir rapidisimo (osea, el buscar).

Asi que generas un funcion que te retorne el rango de hexadecimales validos, lo haseahs, lo guardas en la tabla y luego le haces hash al que quieres atacar y lo buscas en tu tabla de ataques. *Pufff* Sale en milisegundos. No tienes que hace CUDA ni nada raro con esto.
__________________
El malabarista.
Responder Con Cita
  #15  
Antiguo 22-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
lo que dices es buena solucion pero tiene varias pegas. La primera es que crear una rainbow table se demoraria incluso mas que la brute force convencional ya que al tener que realizar las mismas operaciones y ademas tener que ir guardando los resultados en la tabla hace que demore mas aun. La otra pega es el tamaño de las rainbow tables, he llegado a ver tablas hasta de 40 gigas por lo que su portabilidad se complica y mucho. Cuando estuve tocando ese tema vi que habia paginas que tenian tablas listas para descargar y tambien habia programas preparados para crearlas pero las dos razones que comento son suficientes como para pensarselo.

Última edición por aguml fecha: 22-10-2014 a las 20:25:51.
Responder Con Cita
  #16  
Antiguo 23-10-2014
Avatar de mamcx
mamcx mamcx is offline
Moderador
 
Registrado: sep 2004
Ubicación: Medellín - Colombia
Posts: 3.911
Poder: 25
mamcx Tiene un aura espectacularmamcx Tiene un aura espectacularmamcx Tiene un aura espectacular
Pero tienes el rando de busqueda acotado, asi que no debe ser tan grande. Ademas con fuerza bruta tienes un algoritmo sequencial donde pagas lo mismo por cada vez que lo ejecutes. Solo es rapido si apuestas a que la respuesta esta al inicio del rango de busqueda. Ademas estas buscando integers. Eso se puede almacenar super-eficiente.
__________________
El malabarista.
Responder Con Cita
  #17  
Antiguo 23-10-2014
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: nov 2007
Posts: 2.195
Poder: 20
escafandra Tiene un aura espectacularescafandra Tiene un aura espectacular
Entiendo que aguml solo ha pretendido experimentar. Al principio no entendí bien lo que pretendía y escribí un código muy simple que evidentemente no era lo que él buscaba. Siguiendo con la causa original del hilo me permito aportar un código usando C, sin ayuda de cadenas estilo delphi, como él usa, mucho más eficiente.

He usado un serial como éste: FAB1AF04. La función de aguml ha dado con el resultado en 262,875 segundos, mientras que la función que propongo ha tardado 8,656 segundos en un i7. La diferencia es más que notable: 30 veces más rápido, y dedicándole un poco más de tiempo, seguro que se le puede hacer rendir algo más:

Código PHP:
bool FuerzaBruta(charSerialcharSalidacharRango)
{
  
int L strlen(Serial);
  
int R strlen(Rango);
  
int ni;
  
bool Error true;

  for(
n=0n<Ln++) Salida[n] = *Rango;
  
Salida[n] = 0;
  
int f;
  for(
int r=0; ; r++){
    *
Salida Rango[r%R];
    
//acarreo
    
for(int c=0Salida[c]==*Rango && r>1c++){
      for(
i=0Rango[i] && Rango[i]!=Salida[c+1]; i++);
      
Salida[c+1] = Rango[(i+1)%R];
    }
    if(!(
Error strcmp(SalidaSerial))) break;
  }
  return !
Error;

Saludos.
Responder Con Cita
  #18  
Antiguo 23-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
tengo que probarlo, se ve mas corto y con muy buena pinta.
Responder Con Cita
  #19  
Antiguo 23-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Bueno, tuve que mirarlo y tracear porque a simple vista habia cosas que no tenia claras y luego de tracear me sorprendio los tiempos que obtenia y entonces pensé "claro, el empieza de izquierda a derecha el incremento y yo al contrario y como la palabra buscada era F1ACA pues el llegaba antes a la A que yo a la F" entonces decidí dar la vuelta a la cadena tal como ACA1F y mi sorpresa incrementa al ver que casi no cambió el tiempo ya que subió unos 100 milisegundos .
Con esto solo puedo felicitar al maestro Escafandra por un codigo tan bueno como este.

Una cosa mas, le vi un fallo y es que no tiene control de fin de busqueda y si no encuentra la cadena sigue incrementando hasta llegar a desbordar el array por lo que le hice algunos pequeños cambios, el principal para subsanar ese problema y otros para hacerlo mas entendible para mi.

Otra cosa, me dio por probar cambiar los for que inicializan la cadena de tope y la cadena inicial por dos memset y vi que los tiempos se incrementaban solo con eso asi que lo dejé con los for. Supongo que memset hace algo mas internamente que ralentiza un poco el proceso.

Aquí el código final:
Código PHP:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   
AnsiString Rango "0123456789ABCDEF"//Rango de caracteres que se usará para la fuerza bruta
   
AnsiString cadena "KMK;P";//"P;KMK"; //Cadena a buscar. Le he aplicado un calculo usando la funcion CalculosSerial
   
bool retval;
   
double tiempoInicialtiempoFinal;
   
char *Salida = new char[cadena.Length()+1];
   
memset(Salida,'\n',(cadena.Length()+1));

   
Form1->WindowState wsMinimized//Minimizamos el form para que el usuario no pueda pulsar el boton ni nada

   
tiempoInicial GetTickCount(); //Obtenemos el tiempo de entrada

   
retval FuerzaBruta(cadena.c_str(), SalidaRango.c_str());

   if(
retval == false){ //Si no se encontró avisamos
      
ShowMessage("No se encontró el valor");
   }else{
      
tiempoFinal GetTickCount(); //obtenemos el tiempo de salida

      
ShowMessageAnsiString().sprintf"Valor hexadecimal: %s\n"
                                         "Se han tardado %s segundos en encontrarlo."
,
                                         
SalidaFormatFloat("0.000",(tiempoFinal tiempoInicial) /1000)));
   }
   
Form1->WindowState wsNormal//volvemos a restaurar el form
   
delete [] Salida;
}
//---------------------------------------------------------------------------

bool FuerzaBruta(charSerialcharSalidacharRango)
{
   
int largoSerial strlen(Serial); //Obtengo el largo de la cadena del serial
   
int largoRango strlen(Rango); //Obtengo el largo de la cadena del rango
   
int n//Es usado como un contador auxiliar para rellenar inicialmente la cadena de salida y la de tope
   
int posEnRango//Es usada para obtener la posicion en el rango
   
bool retval false//El valor que contenga esta variable será lo que retornemos al salir
   
bool salir false//La uso para indicar cuando debo salir del bucle de fuerza bruta
   
char *CadenaFinal//Es la cadena obtenida de aplicarle calculos a la cadena de salida
   
char *CadenaTope//Esta cadena contendrá el tope de busqueda y si llegamos a ella y no encontramos el valor bueno saldremos con false

   //Reservamos memoria para la cadena final y ponemos el valor de fin de cadena al final de esta
   
CadenaFinal = new char[largoSerial+1];
   
CadenaFinal[largoSerial]=0;

   
//Reservamos memoria para la cadena tope
   
CadenaTope = new char[largoSerial+1];

   
//Para inicializar la cadena de salida la rellenamos con el primer valor del rango y la cerramos con el caracter de fin de cadena
   
for(n=0n<largoSerialn++) Salida[n] = *Rango;
   
Salida[n] = 0;

   
//Para inicializar la cadena de tope la rellenamos con el ultimo valor del rango y la cerramos con el caracter de fin de cadena
   
for(n=0n<largoSerialn++) CadenaTope[n] = Rango[largoRango-1];
   
CadenaTope[n] = 0;

   
//Bucle de fuerza bruta
   
for(unsigned int contador=0salir != truecontador++){
      *
Salida Rango[contador largoRango];

      
//Aqui realizamos el acarreo cuando se ha llegado al ultimo valor del rango en la columna
      
for(int columna=0Salida[columna]==*Rango && contador>1columna++){

         
//Recorremos el bucle hasta que encontramos el caracter de la siguiente columna de la cadena de salida en la cadena del rango
         //En posEnRango tendremos su posicion del caracter al salir
         
for(posEnRango=0Rango[posEnRango] && Rango[posEnRango]!=Salida[columna+1]; posEnRango++);

         
//Aqui obtenemos el resto de dividir la posicion en el rango obtenida en el for + 1 entre el largo del rango
         //El resultado es el indice que usaremos para asignar el caracter de la siguiente columna
         //Si el caracter de la siguiente columna es el ultimo posible, i+1 será igual al largo del rango
         //con lo que el resto será 0 y asignariamos el valor del primer caracter del rango a la siguiente columna
         
Salida[columna+1] = Rango[(posEnRango+1) % largoRango];
      }

      
//Hacemos los calculos deseados con la cadena y obtenemos el resultado en CadenaFinal
      
CalculosSerial(SalidaCadenaFinal);

      if(
strncmp(CadenaFinalSeriallargoSerial) == 0)
      { 
//Si CadenaFinal es igual a la cadena que estamos buscando salimos del bucle
         
retval=true;
         
salir true;
      }
      else if(
strncmp(SalidaCadenaTopelargoSerial) == 0)
      { 
//Si la cadena es igual al tope querrá decir que ya rrecorrimos todo y no se encontró así que salimos del bucle
         
salir true;
      }
   }

   
//Liberamos la memoria
   
delete [] CadenaFinal;
   
delete [] CadenaTope;

   
//Retornamos indicando si la busqueda tuvo exito o no
   
return retval;
}
//---------------------------------------------------------------------------

//Aqui realizariamos los calculos necesarios con el serial
void CalculosSerial(char *Serialchar *Salida)
{
   
int largo strlen(Serial);

   
//Yo simplemente le sumo 10 a cada caracter por ejemplo
   
for(int x=0x<largox++)
      
Salida[x] = Serial[x] + 10;
}
//--------------------------------------------------------------------------- 
y una captura con todos los tiempos (los tres codigos que yo realicé y este ultimo que he llamado "prueba 4"):
Clic aqui para ver imagen

Alucinante la mejora.
Mil gracias amigos.

Última edición por aguml fecha: 23-10-2014 a las 19:17:30.
Responder Con Cita
  #20  
Antiguo 23-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Otro posible (aunque no se hasta que punto probable) fallo. El contador que se usa en el for principal puede llegar a desbordarse (en mi maquina quizas en un par de eones jejeje) ya que incrementa continuamente y dependiendo de lo grande del serial a buscar podria ocurrir.
Lo he solucionado poniendo la siguiente linea al final del for que se encarga del acarreo:
Código PHP:
//Cada vez que llegamos aqui, contador llega siendo multiplo del largo del rango por lo que, para evitar un posible desbordamiento
//de la variable contador, cada vez que entre aquí le asignaremos el valor del largo del rango para curarnos en salud
contador largoRango
Sinceramente no se en que interviene esto pero desde que lo hice los tiempos han mejorado algo mas.
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Seleccionar un determinado rango de caracteres en un memo ErikMdqqq C++ Builder 7 02-08-2013 04:51:49
Es posible crear bucle controlado José Luis Garcí Varios 5 05-07-2011 11:04:54
Crear codigo de Fuerza Bruta kurono Varios 12 31-01-2011 17:46:26
Como crear un bucle con TEdit's axlrafael OOP 12 08-05-2008 20:22:48
Cerrar Form "fuerza bruta" MaMu Varios 3 22-05-2007 20:59:50


La franja horaria es GMT +2. Ahora son las 10:23:11.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi