Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 05-03-2007
teletranx teletranx is offline
Miembro
 
Registrado: feb 2004
Ubicación: Chile
Posts: 112
Poder: 21
teletranx Va por buen camino
Cool Randomizando al Enemigo

Saludos

Mi problema es el siguiente:

Tengo una aplicación en VB.Net, la cual la estoy pasando a Delphi.

En una de sus partes utiliza Randomize y Rnd.
La cual genera una Semillas, para generar 5 números las cuales se sumas a cada cifra de una fecha juliana. Posteriormente genero más números, con los cuales se crea una cadena.
Ya que estoy pasando la aplicación por secciones y se esta utilizando, la parte que valida la cadena esta en VB.net
La cadena que genero en Delphi son distinta, aún que utilice la misma semilla.
Necesito sale como hacer para que lo que genero en Delphi sea lo mismo que en VB
Ejemplo semillas 29 en VB genera 29-19-30-33-21
en Delphi genera 32-13-29-16-31.

Funciones utilizadas

VB Delphi
Randomize Randomize
Randomize(<Semilla>) RandSeed := <Semilla>
Rnd(<Nro>) Random(<Nro>)

Muchas Gracias

JC

P.D. Se podrá Utilizar los API de Windows?

Última edición por teletranx fecha: 05-03-2007 a las 23:40:09.
Responder Con Cita
  #2  
Antiguo 06-03-2007
Mick Mick is offline
Miembro
 
Registrado: may 2003
Posts: 405
Poder: 21
Mick Va por buen camino
Es que estas utilizando funciones para generar numeros "aleatorios" seria un milagro que en distinto lenguajes te saliesen los mismos numeros, para ello tendrian que usar el mismo metodo para generarlos.

Es mas segun el compilador y sistema operativo que se use, hasta seria posible que el mismo programa generase distintos numeros en distintos ordenadores, e incluso en saliesen distintos numeros en el mismo ordenador pero en distintos momentos. Incluso en distintos compiladores o distintas versiones de delphi o distintas versiones de las librerias .Net te podrian salir numeros distintos.

Imaginate que haces el programa para .net, y parece que funcioan todo perfectamente es posible que mañana o pasado a dentro de un mes, el usuario actualize windows, se instale una version .net mas moderna y el programa falle porque se empiecen a generar numeros distintos.

No puedes considerar que las funciones de generacion de numeros aleatorios te van a dar los mismos resultados, si quiere hacer esto no uses rand, tendras que implementar tu propia funcion de generacion de numeros.
Responder Con Cita
  #3  
Antiguo 06-03-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
¿Como haces para generar esta secuencia (32-13-29-16-31) en delphi? ¿que semilla? ¿que valor le pasas a la función random? Porque yo no puedo conseguir la misma secuencia con un valor de semilla de 29.

Código Delphi [-]
var
  i: integer;
  Str: string;
begin
  Str:= '';
  RandSeed:= 29;
  for i:= 1 to 5 do
  begin
     Str:= Str + IntToStr(Random(x)) + ' / ';
  end;
  ShowMessage(Str);
end;

Ningún valor de x entre 1 y 1000 me genera la secuencia que tu indicas en tu mensaje.

En cuanto a simular la funcion Rnd de Visual Basic, lo podriamos intentar de la siguiente manera:
Código Delphi [-]
var
  // Variable global
  Semilla: Cardinal;

function VBRnd: Single;
begin
  Semilla:= (Semilla *  $43fd43fd + $c39ec3) and $ffffff;
  Result:= Semilla / 16777216.0;
end;

Tal como indican en la pagina de microsoft:
http://support.microsoft.com/kb/231847

El problema es inicializar el valor de la semilla, ya que Randomize utiliza un método bastante complejo, así que si me puedes pasar varias secuencias (los números decimales no los enteros) y los parámetros que le pasaste al Randomize para generar cada una de ellas, me seria muy útil para comprobar mi traducción de la función Randomize.
Responder Con Cita
  #4  
Antiguo 06-03-2007
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.040
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por seoane
[..][..]El problema es inicializar el valor de la semilla, ya que Randomize utiliza un método bastante complejo, así que si me puedes pasar varias secuencias (los números decimales no los enteros) y los parámetros que le pasaste al Randomize para generar cada una de ellas, me seria muy útil para comprobar mi traducción de la función Randomize.
Seoane y sus retos, no deja escapar ni una pregunta de las suyas

Por cierto, si se quiere valores "aleatorios", ¿por qué quiéres que salgan los mismos valores?, ya no serían aleatorios
Responder Con Cita
  #5  
Antiguo 06-03-2007
[basti] basti is offline
Miembro Premium
 
Registrado: ago 2004
Posts: 388
Poder: 20
basti Va por buen camino
Cita:
Empezado por seoane
¿Como haces para generar esta secuencia (32-13-29-16-31) en delphi? ¿que semilla? ¿que valor le pasas a la función random? Porque yo no puedo conseguir la misma secuencia con un valor de semilla de 29.
Sacado de la ayuda de Delphi:
Cita:
Note: Because the implementation of the Random function may change between compiler versions, we do not recommend using Random for encryption or other purposes that require reproducible sequences of pseudo-random numbers.
Como ya apuntaron antes la secuencia puede depender de la versión de Delphi que uses, así que es normal que no consigas la misma secuencia.

Cita:
Por cierto, si se quiere valores "aleatorios", ¿por qué quiéres que salgan los mismos valores?, ya no serían aleatorios
Antes de saber lo anterior, yo utilizaba secuencias con random para hacer encriptaciones sencillas, cuando, por casualidad, vi ese texto en la ayuda de delphi, cambié el sistema.
Responder Con Cita
  #6  
Antiguo 06-03-2007
Avatar de seoane
[seoane] seoane is offline
Miembro Premium
 
Registrado: feb 2004
Ubicación: A Coruña, España
Posts: 3.717
Poder: 24
seoane Va por buen camino
Cita:
Empezado por Casimiro Notevi
Por cierto, si se quiere valores "aleatorios", ¿por qué quiéres que salgan los mismos valores?, ya no serían aleatorios
Pues se utiliza para cifrar información, un cifrado muy pobre, nunca el que usarías para ocultar información importante. Pero como es sencillo, se suele utilizar cuando se esta aprendiendo.

También puede servir para otras cosas, por ejemplo en un juego de cartas podemos utilizar Random para barajar las cartas y guardando la semilla podemos repetir el mismo juego todas la veces que queramos. (Creo que el carta blanca utiliza un método similar)

Cita:
Empezado por basti
Antes de saber lo anterior, yo utilizaba secuencias con random para hacer encriptaciones sencillas, cuando, por casualidad, vi ese texto en la ayuda de delphi, cambié el sistema.
Lo ideal si queremos asegurarnos de que el random no nos va a dejar tirados, es utilizar nuestra propia funciona de random. Ya ves que son solo unas lineas de código. Ahora bien, si queremos un poquito de seriedad, la API de windows cuenta con su propio generador de números aleatorios.

De todas formas para encriptar mejor usar alguno de los métodos probadamente seguros, AES, Serpent, etc ... Aguantaran un poco mas un ataque que cualquier método que inventemos nosotros.
Responder Con Cita
  #7  
Antiguo 06-03-2007
teletranx teletranx is offline
Miembro
 
Registrado: feb 2004
Ubicación: Chile
Posts: 112
Poder: 21
teletranx Va por buen camino
Gracias Estoy trabajando con Delphi v7 con el parche y con WinXp Pro Parche 2 Como comente estoy cambiando de un sistema realizado en VB .Net a Delphi, lo estoy cambiando de partes. En una parte existe este.
En VB
Código:
         
Rnd(-1)           
Randomize(qq0)                                                                                       
qq1 = CInt(Int(24 * Rnd() + 11))                                                                          
qq2 = CInt(Int(24 * Rnd() + 11))                                                                       
qq3 = CInt(Int(24 * Rnd() + 11))           
qq4 = CInt(Int(24 * Rnd() + 11))             
qq5 = CInt(Int(24 * Rnd() + 11))
En Delphi
Código Delphi [-]
 
Random(-1);     
RandSeed := qq0;     
qq1 := StrToInt( FloatToStr(Int(24 * Random + 11)));     
qq2 := StrToInt( FloatToStr(Int(24 * Random + 11)));     
qq3 := StrToInt( FloatToStr(Int(24 * Random + 11)));     
qq4 := StrToInt( FloatToStr(Int(24 * Random + 11)));     
qq5 := StrToInt( FloatToStr(Int(24 * Random + 11)));
Donde qq0 es 29 la Semilla El problema que aún no puede utilizar otro sistema de encriptación, ya que la aplicación la están utilizando. Por mi parte yo utilizo los componentes DCPcrypt Cryptographic
Lo otro, con la misma aplicación VB en WinXp Pro y Server 2003 generan lo mismo.
lo otro, cual será en método utiliza VB, ya que he leído más de 10. lo otro, se probó random en delphi con semilla iguales en varios equipos distintos y generando los mismo valores.
Gracias
Espero como siempre sus valiosos comentarios.
JC

Última edición por teletranx fecha: 06-03-2007 a las 22:59:26.
Responder Con Cita
  #8  
Antiguo 06-03-2007
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
Que tal si planteas *primero* que quieres?

Aunque seguro es tecnicamente posible reproducir el algoritmo (como usando Reflector para ver el codigo fuente en .NET) la verdad tampoco le veo el sentido a depender de una funcion aleatoria...
__________________
El malabarista.
Responder Con Cita
  #9  
Antiguo 06-03-2007
teletranx teletranx is offline
Miembro
 
Registrado: feb 2004
Ubicación: Chile
Posts: 112
Poder: 21
teletranx Va por buen camino
Nuevamente, La aplicación que se esta utilizando en varios lugares esta en VB.net, se esta cambiando por partes, me encontré que utilizaban random para generar una key. Como se esta cambiando a Delphi y mis jefes quieren trabajar con esa esquema de generar key. (el que sabe sabe y el que no es jefe). El esquema es muy fácil, una fecha se cambia a formato juliano y se descompone en los diferentes dígito, lo cuales se buscan en una cadena de caracteres y se combinan para crear una key de 31 de largo, en donde esta la fecha y la semilla y otros caracteres que se chequean. Los cuales salen tambien de la semilla. JC
Responder Con Cita
  #10  
Antiguo 06-03-2007
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Cita:
Empezado por seoane
El problema es inicializar el valor de la semilla, ya que Randomize utiliza un método bastante complejo, así que si me puedes pasar varias secuencias (los números decimales no los enteros) y los parámetros que le pasaste al Randomize para generar cada una de ellas, me seria muy útil para comprobar mi traducción de la función Randomize.
Pues, si empleas randomize es muy difícil que logres conseguir repetir la secuencia...
Si realmente deseas obtener la misma secuencia de los resultados no emples randomize e ingresa SIEMPPRE el mismo valor de semilla.
Ha decir verdad no se si será posible obtener los mismos resultados que en VB.

En cuanto a lo que dice seoane sobre técnicas de encriptación:

Cita:
Empezado por seoane
De todas formas para encriptar mejor usar alguno de los métodos probadamente seguros, AES, Serpent, etc ... Aguantaran un poco mas un ataque que cualquier método que inventemos nosotros.
Es lo ideal... ¿Poco? Tengo entendido que el AES es casi inviolable. Encontrarle la solución por fuerza bruta requerirá de años o décadas.

Cita:
Empezado por Casimiro Notevi
Por cierto, si se quiere valores "aleatorios", ¿por qué quiéres que salgan los mismos valores?, ya no serían aleatorios
Pues, para comparar entre la versión Delphi y VB... al menos asi lo tengo entendido. No creo que para la versión final desee generar una y otra vez la misma secuencia (alli si se usa randomize).

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #11  
Antiguo 06-03-2007
teletranx teletranx is offline
Miembro
 
Registrado: feb 2004
Ubicación: Chile
Posts: 112
Poder: 21
teletranx Va por buen camino
Es una aplicación desarrollada en VB, la cual esta siendo utilizada.
Mi jefe quiere que sigamos con el mismo esquema en la validación.
Hice la validación en Delphi, pero al momento de probar la key generada en nuevo programa no salía bien.
Le explique a mi jefe que al ser distintos compiladores (VB y Delphi) generan con una secuencia distinta.
He leido que existen más de 10 metodos para generar el Random, he probado 5 y ninguna sale la misma secuencia.

Cita:
En que sabe sabe , el que no es jefe
con lo que he leido, se va a falle la validación.

Existirá una API que maneje el Random!..

JC
Responder Con Cita
  #12  
Antiguo 06-03-2007
Mick Mick is offline
Miembro
 
Registrado: may 2003
Posts: 405
Poder: 21
Mick Va por buen camino
Metodos y funciones para generar numeros aleatorios hay infinitos, y cualquiera se puede inventar una nuevo algoritmo para generarlos.

En tu caso solo veo dos opciones:

- Preguntar a microsoft por el algoritmo que usan ellos, veo dificil que te respondan pero bueno.

- Si las semillas a utilizar son pocas, asi como la lista de valores es pequeña, usando el programa original generar una tabla con la lista de valores posibles que generan todas las posibles semillas y utilizar esa tabla en el programa en delphi, en definitiva tener precalculados todos los posibles resultados.

Es mas estos numeros precalculados los utilizaria incluso en el programa original, es una locura generar numeros aleatorios y cruzar los dedos para que siga funcionando bien el sistema todos los dias, ese programa estaria jugando a la ruleta rusa, hoy fallara hoy no fallara ? Hoy decidira microsoft en alguna actualizacion mejorar la libreria de generacion de numeros cambiando el algoritmo y me mandara a la mierda el funcionamiento del programa que tengo instalado en cientos de clientes, si no es hoy sera mañana, dentro de un mes ? Lo siento, pero quien decidio usar ese sistema realmente le quedo la cabeza descansada !!!!!!!!!!

Saludos

Última edición por Mick fecha: 06-03-2007 a las 23:25:14.
Responder Con Cita
  #13  
Antiguo 07-03-2007
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
No hay necesidad de preguntarle a MS.

El codigo desensamblado es mas o menos asi:

Código Delphi [-]
function Random.InternalSample: Integer;
begin
    index := self.inext;
    inextp := self.inextp;
    if (++index >= $38) then
        index := 1;
    if (++inextp >= $38) then
        inextp := 1;
    num := (self.SeedArray[index] - self.SeedArray[inextp]);
    if (num < 0) then
        inc(num, $7fffffff);
    self.SeedArray[index] := num;
    self.inext := index;
    self.inextp := inextp;
    begin
        Result := num;
        exit
    end
end;

function Random.Next(minValue: Integer; maxValue: Integer): Integer;
begin
    if (minValue > maxValue) then
        raise ArgumentOutOfRangeException.Create('minValue', string.Format(CultureInfo.CurrentCulture, Environment.GetResourceString('Argument_MinMaxValue'), New(array[2] of TObject, ( ( 'minValue', 'maxValue' ) ))));
    num := (maxValue - minValue);
    if (num <= $7fffffff) then
        begin
            Result := (((self.Sample * num) as Integer) + minValue);
            exit
        end;
    begin
        Result := ((((self.GetSampleForLargeRange * num) as Int64) as Integer) + minValue);
        exit
    end
end;

function Random.Next: Integer;
begin
    Result := self.InternalSample
end;

function Random.Sample: Double;
begin
    Result := (self.InternalSample * 4.6566128752457969E-10)
end;

function Random.GetSampleForLargeRange: Double;
begin
    num := self.InternalSample;
    if ( {pseudo} (if ((self.InternalSample mod 2) = 0) then 1 else 0) <> 0) then
        num := -num;
    num2 := num;
    inc(num2, 2147483646);
    begin
        Result := (num2 div 4294967293);
        exit
    end
end

NOTA: Es solo una porcion y el desemsamblaje no es perfecto.

Ahora, para una mejor aproximacion quizas el codigo de MONO nos sirva:

Código:
	public class Random
	{
		const int MBIG = int.MaxValue;
		const int MSEED = 161803398;
		const int MZ = 0;

		int inext, inextp;
		int [] SeedArray = new int [56];
		
		public Random ()
			: this (Environment.TickCount)
		{
		}

		public Random (int Seed)
		{
			int ii;
			int mj, mk;

			// Numerical Recipes in C online @ http://www.library.cornell.edu/nr/bookcpdf/c7-1.pdf
			mj = MSEED - Math.Abs (Seed);
			SeedArray [55] = mj;
			mk = 1;
			for (int i = 1; i < 55; i++) {  //  [1, 55] is special (Knuth)
				ii = (21 * i) % 55;
				SeedArray [ii] = mk;
				mk = mj - mk;
				if (mk < 0)
					mk += MBIG;
				mj = SeedArray [ii];
			}
			for (int k = 1; k < 5; k++) {
				for (int i = 1; i < 56; i++) {
					SeedArray [i] -= SeedArray [1 + (i + 30) % 55];
					if (SeedArray [i] < 0)
						SeedArray [i] += MBIG;
				}
			}
			inext = 0;
			inextp = 31;
		}

		protected virtual double Sample ()
		{
			int retVal;

			if (++inext  >= 56) inext  = 1;
			if (++inextp >= 56) inextp = 1;

			retVal = SeedArray [inext] - SeedArray [inextp];

			if (retVal < 0)
				retVal += MBIG;

			SeedArray [inext] = retVal;

			return retVal * (1.0 / MBIG);
		}

		public virtual int Next ()
		{
			return (int)(Sample () * int.MaxValue);
		}

		public virtual int Next (int maxValue)
		{
			if (maxValue < 0)
				throw new ArgumentOutOfRangeException(Locale.GetText (
					"Max value is less then min value."));

			return (int)(Sample () * maxValue);
		}

		public virtual int Next (int minValue, int maxValue)
		{
			if (minValue > maxValue)
				throw new ArgumentOutOfRangeException (Locale.GetText (
					"Min value is greater then max value."));

			uint diff = (uint)(maxValue - minValue);
			if (diff == 0)
				return minValue;

			int result = (int)(Sample () * diff + minValue);
			return ((result != maxValue) ? result : (result - 1));
		}

		public virtual void NextBytes (byte [] buffer)
		{
			if (buffer == null)
				throw new ArgumentNullException ("buffer");

			for (int i = 0; i < buffer.Length; i++) {
				buffer [i] = (byte)(Sample () * (byte.MaxValue + 1)); 
			}
		}

		public virtual double NextDouble ()
		{
			return this.Sample ();
		}
	}
Otra solucion seria crear una DLL en Delphi que haga el codigo de random e invocar desde VB.NET con PInvoke, asi se garantizaria una unica implementacion.
__________________
El malabarista.

Última edición por mamcx fecha: 07-03-2007 a las 16:59:13.
Responder Con Cita
Respuesta



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
Aprender a ser como tu enemigo DarkByte Debates 3 26-05-2004 19:43:50


La franja horaria es GMT +2. Ahora son las 20:01:01.


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