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 tiempoInicial, tiempoFinal;
//Podemos asegurarnos de que el valor de cadena es hexa antes de seguir para evitar problemas
for(int i = 1; i<=cadena.Length() && error != true; i++)
{
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, &Salida, Rango);
if(retval == false){ //Si no se encontró avisamos
ShowMessage("No se encontró el valor");
}else{
tiempoFinal = GetTickCount(); //obtenemos el tiempo de salida
ShowMessage( AnsiString().sprintf( "Valor hexadecimal: %s\n"
"Se han tardado %s segundos en encontrarlo.",
Salida, FormatFloat("0.000",(tiempoFinal - tiempoInicial) /1000)));
}
Form1->WindowState = wsNormal; //volvemos a restaurar el form
}
}
//---------------------------------------------------------------------------
bool FuerzaBruta(AnsiString Serial, AnsiString *Salida, AnsiString Rango)
{
int x, pos = 1;
AnsiString Mascara = "";
char valorInicial, valorFinal; //Es el valor inicial y final de caracter a buscar
bool fin = false, sig = false, retval = 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; z <= 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
x = 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(x != 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.