Duda adivinar numero sin fallar

Iniciado por Beginner Web, 25 Junio 2019, 11:26 AM

0 Miembros y 1 Visitante están viendo este tema.

Beginner Web

Hola tengo una duda sobre este programita que hice, lo que quiero es saber si hay alguna forma de que el usuario adivine siempre en el primer intento pero sin saber el numero aleatorio que almaceno la variable dato, tambien sin trampas, en otras palabras hackear de alguna forma el valor aleatorio obtenido.

Código (cpp) [Seleccionar]
int main()
{
int n, dato, contador=0;
srand(time(NULL));
dato=1+rand()%100;
do{
cout<<"Ingrese un numero: ";
cin>>n;
if(n>dato)
cout<<"Ingrese un numero menor"<<endl;
else if(n<dato)
cout<<"Ingrese un numero mayor"<<endl;
else
cout<<"FELICIDADES, ADIVINASTE!!!"<<endl;
contador++;
}while(n!=dato);
cout<<"Cantidad de intentos: "<<contador<<endl;
system("pause");
return 0;
}


;-) :laugh: :xD >:D :rolleyes: :huh: ;D
7w7

MAFUS

Quieres decir que el generador de números aleatorios adivine el número que piensa una persona?

jmpesp

Si el usuario obtiene la direccion de memoria donde se esta almacenando la variable "dato", tendra el numero aleatorio exacto que se genero.

O si el usuario modifica la funcion rand() para que devuelva siempre el mismo valor (parcheando el binario).

Si a lo que te referis es si el programa es "seguro" (refiriendome a que el numero aleatorio sea realmente aleatorio) tampoco es tan asi...

Es posible predecir el resultado de rand() porque estas usando el timestamp actual como semilla.

RayR

Sí es posible, pero bajo ciertas condiciones. Como dices que sin "trampa", descarto accesos a la memoria de tu programa o modificaciones al mismo. En ese caso, lo que el usuario necesita para adivinar el número generado es saber como está implementada la función rand y conocer la semilla, en este caso, la hora exacta a la que time(NULL) calcula el valor que retornará. En un caso tan simple como tu código de ejemplo, donde time se ejecuta al inicio, esto básicamente equivale a saber a qué hora se ejecuta el programa (hora, minuto y segundo).

El valor retornado por time es el número de segundos transcurridos desde el 1 de enero de 1970. Así que, sabiendo la hora, no es difícil calcular este valor, que se usará como semilla para srand. Podría haber una variación de un segundo, por ejemplo, si tu programa es ejecutado a las 11:30:52, pero el segundo 52 estaba por concluir, puede que time se ejecute a las 11:30:53.

Esto no es sólo teórico. Por ejemplo, en Windows, el valor retornado por rand() la primera vez que se invoque es:

( (semilla * 214013L + 2531011L) >> 16 ) & 0x7fff

Así que si el usuario puede ver la hora, incluyendo segundos, a la que se ejecuta el programa, sí, es bastante factible que pueda adivinar el número al primer o segundo intento.

MAFUS

Pero entonces el usuario sabría qué número aleatorio saldría, violando una de las premisas del enunciado que dice:

Citar... sin saber el numero aleatorio que almaceno la variable dato ...

RayR

Cita de: MAFUS en 26 Junio 2019, 00:21 AM
Pero entonces el usuario sabría qué número aleatorio saldría, violando una de las premisas del enunciado que dice:


¿Es en referencia a mi mensaje? Si es así, realmente no se viola la premisa. Por definición, si el usuario es capaz de deducir el número, significa que sabe el número. Podrá haberlo sabido apenas un segundo (o medio, o una décima) antes de decirlo, pero lo tuvo que saber. No puede saber y no saber al mismo tiempo. Dado que éste no es un foro de esoterismo sino de programación, doy por sentado que cuando Beginner Web escribe "sin saber el numero aleatorio que almaceno la variable dato" se refriere a sin conocer el número a priori, sin husmear en la memoria, o a cualquier otra forma de trampa; es decir, no usa el término "adivinar" en sentido literal, sino refiriéndose a si existe alguna forma efectiva para que el usuario deduzca el número generado.

En mi respuesta proporciono una forma de hacer eso, simplemente sabiendo cómo funciona la generación de números pseudoaleatorios en C (además de voltear a ver la hora al ejecutar el programa) y haciendo unos pocos cálculos sencillos. No considero que esto califique como trampa, de la misma forma que estudiar antes de un examen de álgebra, y por lo tanto, saber cómo se resuelve una ecuación, no es hacer trampa.

@XSStringManolo

Hay opciones más aleatorias.
Yo pongo un for a correr con un i++; --i; i=i+1 hasta 10000.
Pongo un contador static para guardar el tiempo de ejecución.. Utilizo el tiempo de ejecución como seed con high_resolution_clock de <chronos>. Esto ya es aleatorio total. Temperatura procesador, tiempo de acceso a ram del procesador, estado del sistema, numero de procesos, espacio de ram utilizado, temperatura ram, temperatura placa, energía de condensadores... El más mínimo cambio afecta.
Si quieres acrecentar aún más la aletoriedad puedes hacer operaciones paea aumentar el número obtenido antes de usarlo como numero aleatorio. No necesitas ni rand. Puedes operar con el número obtenido y llamar al for cada vez que quieras generar un numero aleatorio.

huchoko

Como todos saben, rand() es seudoaleatorio. Más, la implementación de la función rand() en la librería estándar de C usa el Generador linear congruencial, un algoritmo muy simple para obtener números seudoaleatorios, y es fácilmente predecible.