¿Cómo genero enteros aleatorios dentro de un rango específico en Java?


3507

¿Cómo genero un intvalor aleatorio en un rango específico?

He intentado lo siguiente, pero esos no funcionan:

Intento 1:

randomNum = minimum + (int)(Math.random() * maximum);
// Bug: `randomNum` can be bigger than `maximum`.

Intento 2:

Random rn = new Random();
int n = maximum - minimum + 1;
int i = rn.nextInt() % n;
randomNum =  minimum + i;
// Bug: `randomNum` can be smaller than `minimum`.

Cuando necesita muchos números aleatorios, no recomiendo la clase Random en la API. Tiene un período demasiado pequeño. Prueba el tornado de Mersenne en su lugar. Hay una implementación de Java .
raupach

1
Antes de publicar una nueva respuesta, considere que ya hay más de 65 respuestas para esta pregunta. Por favor, asegúrese de que su respuesta contribuya con información que no se encuentre entre las respuestas existentes.
Janniks

Respuestas:


3803

En Java 1.7 o posterior , la forma estándar de hacerlo es la siguiente:

import java.util.concurrent.ThreadLocalRandom;

// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);

Consulte el JavaDoc relevante . Este enfoque tiene la ventaja de no necesitar inicializar explícitamente una instancia de java.util.Random , que puede ser una fuente de confusión y error si se usa de manera inapropiada.

Sin embargo, a la inversa, no hay forma de establecer explícitamente la semilla, por lo que puede ser difícil reproducir resultados en situaciones en las que eso es útil, como probar o guardar estados de juego o similares. En esas situaciones, se puede utilizar la técnica anterior a Java 1.7 que se muestra a continuación.

Antes de Java 1.7 , la forma estándar de hacerlo es la siguiente:

import java.util.Random;

/**
 * Returns a pseudo-random number between min and max, inclusive.
 * The difference between min and max can be at most
 * <code>Integer.MAX_VALUE - 1</code>.
 *
 * @param min Minimum value
 * @param max Maximum value.  Must be greater than min.
 * @return Integer between min and max, inclusive.
 * @see java.util.Random#nextInt(int)
 */
public static int randInt(int min, int max) {

    // NOTE: This will (intentionally) not run as written so that folks
    // copy-pasting have to think about how to initialize their
    // Random instance.  Initialization of the Random instance is outside
    // the main scope of the question, but some decent options are to have
    // a field that is initialized once and then re-used as needed or to
    // use ThreadLocalRandom (if using at least Java 1.7).
    // 
    // In particular, do NOT do 'Random rand = new Random()' here or you
    // will get not very good / not very random results.
    Random rand;

    // nextInt is normally exclusive of the top value,
    // so add 1 to make it inclusive
    int randomNum = rand.nextInt((max - min) + 1) + min;

    return randomNum;
}

Consulte el JavaDoc relevante . En la práctica, la clase java.util.Random a menudo es preferible a java.lang.Math.random () .

En particular, no es necesario reinventar la rueda de generación de enteros aleatorios cuando hay una API sencilla dentro de la biblioteca estándar para realizar la tarea.


43
Para llamadas donde el maxvalor es Integer.MAX_VALUEposible, se puede desbordar, lo que resulta en a java.lang.IllegalArgumentException. Usted puede tratar con: randInt(0, Integer.MAX_VALUE). Además, si nextInt((max-min) + 1)devuelve el valor más alto (bastante raro, supongo), ¿no se desbordará nuevamente (suponiendo que min y max son valores lo suficientemente altos)? ¿Cómo lidiar con este tipo de situaciones?
Daniel

3
@MoisheLipsker Debe ser que nextLong no tome un límite como nextInteger
mmm

13
@leventov ThreadLocalRandomse agregó a Java 2 años y medio después de esta pregunta por primera vez. Siempre he tenido la firme opinión de que la gestión de la instancia aleatoria está fuera del alcance de la pregunta.
Caso Greg

66
En Android Random rand = new Random ();
Webserveis

55
@Webserveis Esto se aborda en los comentarios del ejemplo. Versión corta: no debe = new Random () para cada llamada a la función, o sus resultados no serán lo suficientemente aleatorios para muchos casos.
Greg Case

1422

Tenga en cuenta que este enfoque es más parcial y menos eficiente que un nextIntenfoque, https://stackoverflow.com/a/738651/360211

Un patrón estándar para lograr esto es:

Min + (int)(Math.random() * ((Max - Min) + 1))

La función de la biblioteca Java Math Math.random () genera un valor doble en el rango [0,1). Tenga en cuenta que este rango no incluye el 1.

Para obtener primero un rango específico de valores, debe multiplicar por la magnitud del rango de valores que desea cubrir.

Math.random() * ( Max - Min )

Esto devuelve un valor en el rango [0,Max-Min), donde 'Max-Min' no está incluido.

Por ejemplo, si lo desea [5,10), debe cubrir cinco valores enteros para poder usar

Math.random() * 5

Esto devolvería un valor en el rango [0,5), donde 5 no está incluido.

Ahora necesita cambiar este rango al rango al que está apuntando. Para ello, agregue el valor mínimo.

Min + (Math.random() * (Max - Min))

Ahora obtendrá un valor en el rango [Min,Max). Siguiendo nuestro ejemplo, eso significa [5,10):

5 + (Math.random() * (10 - 5))

Pero, esto todavía no incluye Maxy está obteniendo un doble valor. Para obtener el Maxvalor incluido, debe agregar 1 a su parámetro de rango (Max - Min)y luego truncar la parte decimal mediante un int. Esto se logra a través de:

Min + (int)(Math.random() * ((Max - Min) + 1))

Y ahí lo tienes. Un valor entero aleatorio en el rango [Min,Max], o según el ejemplo [5,10]:

5 + (int)(Math.random() * ((10 - 5) + 1))

82
La documentación de Sun dice explícitamente que debería usar Random () mejor si necesita un int en lugar de Math.random () que produce un doble.
Lilian A. Moraru

66
Esto está sesgado en comparación con los métodos nextInt stackoverflow.com/a/738651/360211
weston

44
"Sesgado" en este caso significa que después de 2 ^ 53 ejecuciones, algunos números habrán tenido una ocurrencia adicional, en promedio.
Cefalópodo

378

Utilizar:

Random ran = new Random();
int x = ran.nextInt(6) + 5;

El entero xahora es el número aleatorio que tiene un posible resultado de 5-10.



137

Con introdujeron el método ints(int randomNumberOrigin, int randomNumberBound)en la Randomclase.

Por ejemplo, si desea generar cinco enteros aleatorios (o uno solo) en el rango [0, 10], simplemente haga:

Random r = new Random();
int[] fiveRandomNumbers = r.ints(5, 0, 11).toArray();
int randomNumber = r.ints(1, 0, 11).findFirst().getAsInt();

El primer parámetro indica solo el tamaño del IntStreamgenerado (que es el método sobrecargado del que produce un ilimitado IntStream).

Si necesita hacer varias llamadas por separado, puede crear un iterador primitivo infinito a partir de la secuencia:

public final class IntRandomNumberGenerator {

    private PrimitiveIterator.OfInt randomIterator;

    /**
     * Initialize a new random number generator that generates
     * random numbers in the range [min, max]
     * @param min - the min value (inclusive)
     * @param max - the max value (inclusive)
     */
    public IntRandomNumberGenerator(int min, int max) {
        randomIterator = new Random().ints(min, max + 1).iterator();
    }

    /**
     * Returns a random number in the range (min, max)
     * @return a random number in the range (min, max)
     */
    public int nextInt() {
        return randomIterator.nextInt();
    }
}

También puedes hacerlo por doubley longvalores. ¡Espero que ayude! :)


1
Le sugiero que cree una instancia de randomIterator solo una vez. Vea el comentario de Greg Case sobre su propia respuesta.
Naxos84

si puede, ¿puede explicar cuál es el significado de streamSize? El primer parámetro de este método dado streamSize !=0. ¿Cuál es la diferencia si streamSizese da 1/2 / n?
Erfan Ahmed

104

Puede editar su segundo ejemplo de código para:

Random rn = new Random();
int range = maximum - minimum + 1;
int randomNum =  rn.nextInt(range) + minimum;

100

Solo una pequeña modificación de su primera solución sería suficiente.

Random rand = new Random();
randomNum = minimum + rand.nextInt((maximum - minimum) + 1);

Ver más aquí para la implementación de Random


Para mínimo <= valor <máximo, hice lo mismo con Math: randomNum = mínimo + (int) (Math.random () * (máximo-mínimo)); pero el casting no es realmente agradable de ver;)
AxelH

Respuesta duplicada de al menos 7 años de retraso.
Maarten Bodewes

70

ThreadLocalRandomequivalente de clase java.util.Randompara entorno multiproceso. La generación de un número aleatorio se lleva a cabo localmente en cada uno de los hilos. Entonces tenemos un mejor desempeño al reducir los conflictos.

int rand = ThreadLocalRandom.current().nextInt(x,y);

x, y- intervalos, p. ej. (1,10)


66

La Math.Randomclase en Java está basada en 0. Entonces, si escribes algo como esto:

Random rand = new Random();
int x = rand.nextInt(10);

xserá entre 0-9inclusivo.

Entonces, dada la siguiente matriz de 25elementos, el código para generar un número aleatorio entre 0(la base de la matriz) y array.lengthsería:

String[] i = new String[25];
Random rand = new Random();
int index = 0;

index = rand.nextInt( i.length );

Como i.lengthregresará 25, nextInt( i.length )devolverá un número entre el rango de 0-24. La otra opción va con la Math.Randomque funciona de la misma manera.

index = (int) Math.floor(Math.random() * i.length);

Para una mejor comprensión, consulte la publicación en el foro Random Intervals (archive.org) .


+1 para el enlace de captura de pantalla del archivo wayBackMachine y su respuesta sigue siendo una referencia útil para obtener entradas "aleatorias" dentro de un rango.
Tapper7

Me desconcierta por qué instancia el índice a 0.
AjahnCharles

@CodeConfident La indexvariable no afectará el resultado del número aleatorio. Puede optar por inicializarlo de la forma que desee sin tener que preocuparse por cambiar el resultado. Espero que esto ayude.
Matt R

Exactamente ... está completamente sin usar. Lo inicializaría directamente al rand:int index = rand.nextInt(i.Length);
AjahnCharles

O no del todo. int index; \n index = rand...si a uno le gustan las declaraciones y asignaciones en diferentes líneas. Algunos estándares de codificación son más estrictos (y sin un propósito aparente) que otros.
Mark Storer

49

Perdóname por ser fastidioso, pero la solución sugerida por la mayoría, es decir min + rng.nextInt(max - min + 1)), parece peligrosa debido al hecho de que:

  • rng.nextInt(n)no puede alcanzar Integer.MAX_VALUE.
  • (max - min)puede causar desbordamiento cuando mines negativo.

Una solución infalible devolvería resultados correctos para cualquiera min <= maxdentro de [ Integer.MIN_VALUE, Integer.MAX_VALUE]. Considere la siguiente implementación ingenua:

int nextIntInRange(int min, int max, Random rng) {
   if (min > max) {
      throw new IllegalArgumentException("Cannot draw random int from invalid range [" + min + ", " + max + "].");
   }
   int diff = max - min;
   if (diff >= 0 && diff != Integer.MAX_VALUE) {
      return (min + rng.nextInt(diff + 1));
   }
   int i;
   do {
      i = rng.nextInt();
   } while (i < min || i > max);
   return i;
}

Aunque ineficiente, tenga en cuenta que la probabilidad de éxito en el whileciclo siempre será del 50% o más.


¿Por qué no lanzar una IllegalArgumentException cuando la diferencia = Integer.MAX_VALUE? Entonces no necesitas el bucle while.
MP Korstanje

3
@mpkorstanje Esta implementación está diseñada para funcionar con cualquier valor de min <= max, incluso cuando su diferencia es igual o mayor que MAX_VALUE. Ejecutar un ciclo hasta el éxito es un patrón común en este caso, para garantizar una distribución uniforme (si la fuente subyacente de aleatoriedad es uniforme). Random.nextInt (int) lo hace internamente cuando el argumento no es un poder de 2.
Christian Semrau

44

Se puede hacer simplemente haciendo la declaración:

Randomizer.generate(0,10); //min of zero, max of ten

A continuación se muestra su código fuente

Randomizer.java

public class Randomizer {
    public static int generate(int min,int max) {
        return min + (int)(Math.random() * ((max - min) + 1));
    }
}

Es simplemente limpio y simple.


55
Esto podría haber sido una edición del otro ejemplo, ahora es solo una copia flagrante para la reputación. Señalar que la "respuesta con más votos" tampoco es muy directa, puede cambiar.
Maarten Bodewes

1
Eso es correcto @MaartenBodewes. Cuando escribí esta respuesta, la respuesta con la mayoría de los votos anteriores todavía se escribió como una solución similar a un algoritmo. Ahora, la solución anterior ha cambiado mucho y ahora esta respuesta parecía un imitador.
Abel Callejo

Realmente no entiendo por qué esos bits fundamentales de código no son parte de las bibliotecas estándar de Java. ¿Por qué tengo que implementar esto?
Leevi L


31

Pongamos un ejemplo.

Supongamos que deseo generar un número entre 5-10 :

int max = 10;
int min = 5;
int diff = max - min;
Random rn = new Random();
int i = rn.nextInt(diff + 1);
i += min;
System.out.print("The Random Number is " + i);

Déjanos entender esto ...

Inicialice max con el valor más alto y min con el valor más bajo.

Ahora, necesitamos determinar cuántos valores posibles se pueden obtener. Para este ejemplo, sería:

5, 6, 7, 8, 9, 10

Entonces, el conteo de esto sería max - min + 1.

es decir, 10 - 5 + 1 = 6

El número aleatorio generará un número entre 0-5 .

es decir, 0, 1, 2, 3, 4, 5

Agregar el valor mínimo al número aleatorio produciría:

5, 6, 7, 8, 9, 10

De ahí obtenemos el rango deseado.



26

Genere un número aleatorio para la diferencia de min y max utilizando el método nextint (n) y luego agregue un número min al resultado:

Random rn = new Random();
int result = rn.nextInt(max - min + 1) + min;
System.out.println(result);

26

Yo uso esto:

 /**
   * @param min - The minimum.
   * @param max - The maximum.
   * @return A random double between these numbers (inclusive the minimum and maximum).
   */
 public static double getRandom(double min, double max) {
   return (Math.random() * (max + 1 - min)) + min;
 }

Puedes convertirlo en un entero si quieres.


Esta función produce el mismo número una y otra vez. En mi caso fue: 2147483647
sokras

Falla: ¿tiene una función que requiere un doble y luego realiza + 1? Esto ciertamente va en contra del principio de menor sorpresa. ¿Qué sucede si usa min = 0.1 y max = 0.2?
Maarten Bodewes

@sokras que el método llama new Random(verifique el JavaDoc): "Crea un nuevo generador de números aleatorios. Este constructor establece la semilla del generador de números aleatorios en un valor muy probable que sea distinto de cualquier otra invocación de este constructor". Es muy probable que solo implique el uso del tiempo actual como semilla. Si ese tiempo usa milisegundos, las computadoras actuales son lo suficientemente rápidas como para generar el mismo número. Pero además de eso 2147483647 es Integer.MAX_VALUE; la salida obviamente depende de la entrada, que no ha especificado.
Maarten Bodewes

Finalmente encontré el que realmente funciona
Jency el

23

A partir de Java 7, ya no deberías usarlo Random. Para la mayoría de los usos, el generador de números aleatorios de elección es ahora ThreadLocalRandom.

Para bifurcaciones de grupos de unión y flujos paralelos, use SplittableRandom.

Joshua Bloch. Java efectivo Tercera edicion.

A partir de Java 8

Para grupos de unión de fork y flujos paralelos, el uso SplittableRandomque generalmente es más rápido, tiene una mejor independencia estadística y propiedades de uniformidad en comparación con Random.

Para generar un azar inten el rango[0, 1_000]:

int n = new SplittableRandom().nextInt(0, 1_001);

Para generar una int[100]matriz aleatoria de valores en el rango[0, 1_000]:

int[] a = new SplittableRandom().ints(100, 0, 1_001).parallel().toArray();

Para devolver una secuencia de valores aleatorios:

IntStream stream = new SplittableRandom().ints(100, 0, 1_001);

¿Hay alguna razón por la cual el ejemplo incluye a .parallel()? Me parece que generar 100 números aleatorios sería demasiado trivial para justificar el paralelismo.
Johnbot

@ Johnbot Gracias por comentar, tienes razón. Pero, la razón principal fue mostrar una API (por supuesto, la ruta inteligente es medir el rendimiento antes de usar el parallelprocesamiento). Por cierto, para una variedad de 1_000_000elementos, la parallelversión fue 2 veces más rápida en mi máquina en comparación con la secuencial.
Oleksandr Pyrohov

21

Solo usa la clase Random :

Random ran = new Random();
// Assumes max and min are non-negative.
int randomInt = min + ran.nextInt(max - min + 1);

8
No veo nada nuevo aquí que no haya sido publicado en innumerables publicaciones anteriores.
Maarten Bodewes

20

Estos métodos pueden ser convenientes de usar:

Este método devolverá un número aleatorio entre el valor mínimo y máximo proporcionados:

public static int getRandomNumberBetween(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt(max - min) + min;
    if (randomNumber == min) {
        // Since the random number is between the min and max values, simply add 1
        return min + 1;
    } else {
        return randomNumber;
    }
}

y este método devolverá un número aleatorio del valor mínimo y máximo proporcionados (por lo que el número generado también podría ser el número mínimo o máximo):

public static int getRandomNumberFrom(int min, int max) {
    Random foo = new Random();
    int randomNumber = foo.nextInt((max + 1) - min) + min;

    return randomNumber;
}

// Since the random number is between the min and max values, simply add 1. ¿Por qué? ¿Min no cuenta? Por lo general, el rango es [min, max) donde se incluye min y se excluye max. Respuesta incorrecta, rechazada.
Maarten Bodewes

@MaartenBodewes +1 se agrega porque getRandomNumberBetween genera un número aleatorio exclusivo de los puntos finales proporcionados.
Luke Taylor el

1
¡El número min + 1será el doble de probable que el otro número como resultado getRandomNumberBetween!
Lii

19

En caso de tirar un dado, sería un número aleatorio entre 1 y 6 (no entre 0 y 6), así que:

face = 1 + randomNumbers.nextInt(6);

19
int random = minimum + Double.valueOf(Math.random()*(maximum-minimum )).intValue();

O eche un vistazo a RandomUtils de Apache Commons .


Eso es útil, pero ten cuidado con un pequeño defecto: las firmas de métodos son como: nextDouble (double startInclusive, double endInclusive), pero si miras dentro de los métodos, endInclusive debería ser endExclusive.
zakmck

Double.valueOf(Math.random()*(maximum-minimun)).intValue()es una manera bastante ofuscada (e ineficiente) de decir (int)(Math.random()*(maximum-minimun))...
Holger

Falta de coincidencia de ortografía para el mínimo retorno mínimo + Double.valueOf (Math.random () * (máximo - mínimo)). IntValue ();
Hrishikesh Mishra

18

Aquí hay una clase útil para generar al azar intsen un rango con cualquier combinación de límites inclusivos / exclusivos:

import java.util.Random;

public class RandomRange extends Random {
    public int nextIncInc(int min, int max) {
        return nextInt(max - min + 1) + min;
    }

    public int nextExcInc(int min, int max) {
        return nextInt(max - min) + 1 + min;
    }

    public int nextExcExc(int min, int max) {
        return nextInt(max - min - 1) + 1 + min;
    }

    public int nextIncExc(int min, int max) {
        return nextInt(max - min) + min;
    }
}

18

Para generar un número aleatorio "entre dos números", use el siguiente código:

Random r = new Random();
int lowerBound = 1;
int upperBound = 11;
int result = r.nextInt(upperBound-lowerBound) + lowerBound;

Esto le da un número aleatorio entre 1 (inclusive) y 11 (exclusivo), así que inicialice el valor upperBound sumando 1. Por ejemplo, si desea generar un número aleatorio entre 1 y 10, inicialice el número upperBound con 11 en lugar de 10)


18

Puede lograrlo de manera concisa en Java 8:

Random random = new Random();

int max = 10;
int min = 5;
int totalNumber = 10;

IntStream stream = random.ints(totalNumber, min, max);
stream.forEach(System.out::println);

17
public static Random RANDOM = new Random(System.nanoTime());

public static final float random(final float pMin, final float pMax) {
    return pMin + RANDOM.nextFloat() * (pMax - pMin);
}

16

Otra opción es simplemente usar Apache Commons :

import org.apache.commons.math.random.RandomData;
import org.apache.commons.math.random.RandomDataImpl;

public void method() {
    RandomData randomData = new RandomDataImpl();
    int number = randomData.nextInt(5, 10);
    // ...
 }

16

Encontré este ejemplo Generar números aleatorios :


Este ejemplo genera enteros aleatorios en un rango específico.

import java.util.Random;

/** Generate random integers in a certain range. */
public final class RandomRange {

  public static final void main(String... aArgs){
    log("Generating random integers in the range 1..10.");

    int START = 1;
    int END = 10;
    Random random = new Random();
    for (int idx = 1; idx <= 10; ++idx){
      showRandomInteger(START, END, random);
    }

    log("Done.");
  }

  private static void showRandomInteger(int aStart, int aEnd, Random aRandom){
    if ( aStart > aEnd ) {
      throw new IllegalArgumentException("Start cannot exceed End.");
    }
    //get the range, casting to long to avoid overflow problems
    long range = (long)aEnd - (long)aStart + 1;
    // compute a fraction of the range, 0 <= frac < range
    long fraction = (long)(range * aRandom.nextDouble());
    int randomNumber =  (int)(fraction + aStart);    
    log("Generated : " + randomNumber);
  }

  private static void log(String aMessage){
    System.out.println(aMessage);
  }
} 

Un ejemplo de ejecución de esta clase:

Generating random integers in the range 1..10.
Generated : 9
Generated : 3
Generated : 3
Generated : 9
Generated : 4
Generated : 1
Generated : 3
Generated : 9
Generated : 10
Generated : 10
Done.

14

Es mejor usar SecureRandom en lugar de solo Random.

public static int generateRandomInteger(int min, int max) {
    SecureRandom rand = new SecureRandom();
    rand.setSeed(new Date().getTime());
    int randomNum = rand.nextInt((max - min) + 1) + min;
    return randomNum;
}

1
Esto no es tan bueno, porque si se ejecuta en el mismo milisegundo, obtendrá el mismo número, debe colocar la inicialización rand y el setSeet fuera del método.
maraca

Necesitas semilla, sí, pero usando SecureRandom.
grep

Lo siento, pero el que rechazó la solicitud de cambio no tiene idea de la programación de Java. Es una buena sugerencia, pero como está mal, porque si se ejecuta en el mismo milisegundo, dará el mismo número, no al azar.
maraca

La solución correcta no se encuentra en ningún lado, no mucha gente conoce los bloques de inicializador estático ... eso es lo que debe usar para establecer la semilla: 1: private static int SecureRandom rand = new SecureRandom();2: static {3: rand.setSeed(...);4:}
maraca

55
No hay absolutamente ninguna necesidad de sembrar SecureRandom, será sembrado por el sistema. Llamar directamente setSeedes muy peligroso, puede reemplazar la semilla (realmente aleatoria) con la fecha. Y eso ciertamente no dará como resultado una SecureRandom, ya que cualquiera puede adivinar el tiempo e intentar sembrar su propia SecureRandominstancia con esa información.
Maarten Bodewes

13

Aquí hay una muestra simple que muestra cómo generar un número aleatorio de cerrado [min, max] rango , mientrasmin <= max is true

Puede reutilizarlo como campo en la clase de hoyo, también teniendo todos Random.class métodos en un solo lugar

Ejemplo de resultados:

RandomUtils random = new RandomUtils();
random.nextInt(0, 0); // returns 0
random.nextInt(10, 10); // returns 10
random.nextInt(-10, 10); // returns numbers from -10 to 10 (-10, -9....9, 10)
random.nextInt(10, -10); // throws assert

Fuentes:

import junit.framework.Assert;
import java.util.Random;

public class RandomUtils extends Random {

    /**
     * @param min generated value. Can't be > then max
     * @param max generated value
     * @return values in closed range [min, max].
     */
    public int nextInt(int min, int max) {
        Assert.assertFalse("min can't be > then max; values:[" + min + ", " + max + "]", min > max);
        if (min == max) {
            return max;
        }

        return nextInt(max - min + 1) + min;
    }
}

13
rand.nextInt((max+1) - min) + min;

Esto está funcionando bien.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.