aleatorios ou randomicos em Java (o termo randomico e correto mas prefiro aleatorio), entender alguns termos relacionados ao assunto, como pseudoaleatorio e deterministico, verificar alguns conceitos de previsibilidade e seguranca envolvidos nestes valores gerados e algumas formas de geracao de valores dependendo do objetivo.Algoritmos pseudoaleatoriosEm Java nos temos geradores de numeros pseudoaleatorios, mas o que significa isso? Significa que uma sequencia de numeros gerados por estes algoritmos aparentam ser aleatorios mas nao sao, na verdade eles sao baseados em um algoritmo que possui uma logica que gera numeros em uma sequencia extraida de uma valor inicial, a semente.Semente (seed)Todos algoritmos de geracao pseudoaleatoria partem de um conjunto de valores iniciais, chamado semente, para realizar os calculos de obtencao de cada numero gerado em uma sequencia deterministica.DeterministicoOs algoritmos pseudoaleatorios sao deterministicos pois, conhecendo-se o algoritmo e a semente utilizada e possivel replicar (determinar) uma sequencia de valores gerada previamente. Ou, dependendo do caso, conhecendo-se o algoritmo e a uma parte da sequencia e possivel encontrar a semente atraves de ataque de forca bruta.RNG - Random Number Generator ou Gerador de Numeros AleatoriosOs "fabricantes" de numeros aleatorios. Em Java e uma classe que implemente um algoritmo gerador de valores aleatorios. Passaremos a utilizar somente RNG daqui em diante.java.lang.Math.randomDentro da classe utilitaria java.lang.Math existe o metodo estatico random que e capaz de gerar numeros pseudoaleatorios do tipo double compreendidos entre 0,0 (inclusive) e 1,0. Este metodo de geracao de numeros aleatorios e o metodo mais utilizado, principalmente por iniciantes na linguagem, mas tambem por ser mais "simples" de trabalhar.Na primeira chamada ao metodo Math.random sera criada uma instancia estatica de um RNG padrao (new Random()) com semente baseada no momento da execucao (System.currentTimeMillis()), e apos isso, todas as chamadas usarao o mesmo RNG.Este metodo de geracao tem a vantagem de manter apenas uma instancia de um RNG durante toda a execucao do seu sistema sem a necessidade de implementacoes adicionais. Mas as chamadas sao sincronizadas, o que leva a degradacao de performance em sistemas multithread que necessitem realizar chamadas concorrentes e em grande volume.public class NumerosAleatorios { public static void main(String[] args) { // Gerando numeros reais de 0,0 ate 0,999999... for(int i = 0; i < 50; i++) { System.out.print(Math.random() + " "); } System.out.print("\n"); // Gerando numeros inteiros de 15 ate 24 for(int i = 0; i < 50; i++) { int n = (int)(Math.random() * 10) + 15; System.out.print(n + " "); } }}java.util.RandomComo vimos acima, o RNG padrao do Java e obtido atraves da classe Random. Ao trabalharmos diretamente com esta classe temos acesso a diversos metodos de geracao de valores aleatorios, bem como a possibilidade de definir a semente. A chamada Math.random e um atalho para Random.nextDouble que retornara um valor double, mas podemos obter, tambem, valores inteiros e boolean entre outros.Como esta classe permite que possamos definir ou redefinir a semente o teste que iremos ver logo abaixo, sempre que executado, retornara o mesmo resultado, exatamente a mesma sequencia de valores, expondo assim o determinismo do algoritmo de uma forma mais clara.public class NumerosAleatorios { public static void main(String[]