Ver Mensaje Individual
  #3  
Antiguo 20-10-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Reputación: 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