Eu também escrevi um tutorial sobre este tópico no passado, onde geramos strings alfanuméricas aleatórias em PHP. Comecei esse post dizendo que quase nenhum evento é verdadeiramente aleatório e a mesma coisa se aplica a números aleatórios ou geração de strings.
Neste tutorial, mostrarei como gerar strings alfanuméricas pseudo-aleatórias em JavaScript.
Gerando números aleatórios em JavaScript
Vamos começar com a geração de números aleatórios. O primeiro método que vem à mente é Math.random()
que retorna um número pseudo-aleatório de ponto flutuante. O número aleatório sempre será maior ou igual a 0 e menor que 1.
A distribuição dos números retornados nesse intervalo é quase uniforme, portanto, o método pode funcionar bem para gerar números aleatórios sem viés perceptível no uso diário. Aqui está a saída de dez chamadas para o Math.random()
método:
1 |
for(let i = 0; i < 10; i++) { |
2 |
console.log(Math.random()); |
3 |
}
|
4 |
|
5 |
/* Outputs:
|
6 |
0.9981169188071801
|
7 |
0.7073616929117277
|
8 |
0.05826679080842556
|
9 |
0.30779242012809105
|
10 |
0.37282814053539926
|
11 |
0.8991639574910759
|
12 |
0.5851162879630685
|
13 |
0.40572834956467063
|
14 |
0.5286480734412005
|
15 |
0.07898699710613699
|
16 |
*/
|
Gerando números inteiros aleatórios dentro do intervalo
Como você viu na seção anterior, Math.random()
nos dará números aleatórios no intervalo de 0 (inclusivo) a 1 (exclusivo). Digamos que queremos números inteiros aleatórios no intervalo de 0 (inclusivo) a 100 (exclusivo). Tudo o que precisamos fazer aqui é multiplicar o intervalo original por 100.
Tomando o primeiro valor de saída do trecho de código acima como exemplo, 0,9981169188071801 se tornará 99,81169188071801 quando multiplicado por 100. Agora, podemos usar o Math.floor()
método que arredondará para baixo e retornará o maior inteiro menor ou igual a 99,81169188071801. Em outras palavras, isso nos dará 99.
O trecho de código a seguir irá percorrer um loop 10 vezes para mostrar todas essas etapas aplicadas a números diferentes.
1 |
const max_limit = 100; |
2 |
|
3 |
for(let i = 0; i < 10; i++) { |
4 |
let random_float = Math.random(); |
5 |
let scaled_float = random_float * max_limit; |
6 |
let random_integer = Math.floor(scaled_float); |
7 |
|
8 |
let rf_str = random_float.toString().padEnd(20, ' '); |
9 |
let sf_str = scaled_float.toString().padEnd(20, ' '); |
10 |
let ri_str = random_integer.toString().padStart(2, ' '); |
11 |
|
12 |
console.log(`Random Float: ${rf_str} Scaled Float: ${sf_str} Random Integer: ${ri_str}`); |
13 |
}
|
14 |
|
15 |
/* Outputs:
|
16 |
Random Float: 0.7976037763162469 Scaled Float: 79.76037763162469 Random Integer: 79
|
17 |
Random Float: 0.3794078358214559 Scaled Float: 37.94078358214558 Random Integer: 37
|
18 |
Random Float: 0.5749118617425708 Scaled Float: 57.49118617425708 Random Integer: 57
|
19 |
Random Float: 0.7110572178100005 Scaled Float: 71.10572178100006 Random Integer: 71
|
20 |
Random Float: 0.9157559644743132 Scaled Float: 91.57559644743132 Random Integer: 91
|
21 |
Random Float: 0.8773095295734263 Scaled Float: 87.73095295734264 Random Integer: 87
|
22 |
Random Float: 0.7714603913623834 Scaled Float: 77.14603913623834 Random Integer: 77
|
23 |
Random Float: 0.6431998616346499 Scaled Float: 64.31998616346499 Random Integer: 64
|
24 |
Random Float: 0.7909155691442253 Scaled Float: 79.09155691442254 Random Integer: 79
|
25 |
Random Float: 0.1219575935563590 Scaled Float: 12.19575935563590 Random Integer: 12
|
26 |
*/
|
Agora que você entende a lógica por trás da multiplicação e nivelamento, podemos escrever uma função que gera um número inteiro aleatório dentro do limite máximo.
1 |
function max_random_number(max) { |
2 |
return Math.floor(Math.random() * max); |
3 |
}
|
4 |
|
5 |
for(let i = 0; i < 10; i++) { |
6 |
console.log(max_random_number(100)); |
7 |
}
|
8 |
|
9 |
/* Outputs:
|
10 |
35
|
11 |
23
|
12 |
92
|
13 |
94
|
14 |
42
|
15 |
9
|
16 |
12
|
17 |
56
|
18 |
40
|
19 |
21
|
20 |
*/
|
E se você quiser gerar números aleatórios acima de um valor mínimo especificado, mas abaixo do valor máximo?
Nesse caso, você pode adicionar o valor mínimo antecipadamente para garantir que o número gerado seja pelo menos igual ao valor mínimo. Depois disso, você pode simplesmente gerar um número aleatório e escalá-lo por max - min
antes de adicioná-lo ao valor mínimo possível.
1 |
function min_max_random_number(min, max) { |
2 |
return min + Math.floor(Math.random() * (max - min)); |
3 |
}
|
4 |
|
5 |
for(let i = 0; i < 10; i++) { |
6 |
console.log(min_max_random_number(50, 100)); |
7 |
}
|
8 |
|
9 |
/* Outputs:
|
10 |
96
|
11 |
81
|
12 |
95
|
13 |
56
|
14 |
73
|
15 |
72
|
16 |
71
|
17 |
90
|
18 |
51
|
19 |
53
|
20 |
*/
|
Gere números aleatórios criptograficamente seguros
o Math.random()
método não é adequado para gerar números aleatórios criptograficamente seguros, mas o Crypto.getRandomValues()
método pode nos ajudar aqui. Este método preenche a matriz passada com números pseudo-aleatórios criptograficamente seguros. Lembre-se de que o algoritmo usado para gerar esses números aleatórios pode variar entre os agentes do usuário.
Como mencionei anteriormente, você precisa passar um número inteiro TypedArray
ao método para que ele o preencha com valores aleatórios. O conteúdo original da matriz será substituído. O código a seguir preencherá nossa matriz de 10 elementos com números inteiros aleatórios.
1 |
let random_values = new Uint8Array(10); |
2 |
console.log(random_values); |
3 |
// Outputs: Uint8Array(10) [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
|
4 |
|
5 |
crypto.getRandomValues(random_values); |
6 |
console.log(random_values); |
7 |
// Outputs: Uint8Array(10) [ 207, 209, 1, 145, 70, 111, 21, 141, 54, 200 ]
|
o Unit8Array()
O construtor nos deu uma matriz de 10 inteiros sem sinal de 8 bits. Os valores da matriz são todos inicializados com zero.
Uma vez que passamos esta matriz para o nosso getRandomValues()
método, o valor dos números aleatórios ficará entre 0 e 255. Você pode usar outras matrizes digitadas para gerar números aleatórios em intervalos diferentes. Por exemplo, usando um Int8Array()
O construtor nos dará uma matriz com valores inteiros entre -128 e 127. Da mesma forma, usando um Uint16Array()
nos dará uma matriz com valores inteiros até 65.535.
1 |
let random_values = new Int8Array(10); |
2 |
console.log(random_values); |
3 |
// Outputs: Int8Array(10) [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
|
4 |
|
5 |
crypto.getRandomValues(random_values); |
6 |
console.log(random_values); |
7 |
// Outputs: Int8Array(10) [ -82, -106, 87, 64, 42, -36, -53, 27, -38, 4 ]
|
8 |
|
9 |
|
10 |
let random_values = new Uint16Array(10); |
11 |
console.log(random_values); |
12 |
// Outputs: Uint16Array(10) [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
|
13 |
|
14 |
crypto.getRandomValues(random_values); |
15 |
console.log(random_values); |
16 |
// Outputs: Uint16Array(10) [ 47615, 60195, 53177, 15169, 215, 4928, 12200, 6307, 30320, 20271 ]
|
Gere uma string alfanumérica aleatória em JavaScript
Agora usaremos o conhecimento obtido na seção anterior para gerar strings alfanuméricas aleatórias em JavaScript.
O conceito é muito simples. Começaremos com uma string que contém todos os nossos caracteres desejados. Nesse caso, a string consistirá em letras minúsculas, letras maiúsculas e números de 0 a 9. Você provavelmente já sabe que podemos acessar o caractere em uma determinada posição em uma string passando-lhe um valor de índice.
Tudo o que precisamos fazer para gerar strings alfanuméricas aleatórias é gerar números aleatórios e, em seguida, acessar o caractere nesse índice aleatório para anexá-lo à nossa string aleatória. O trecho de código a seguir envolve tudo em uma pequena função interessante:
1 |
const char_set = 'abcdefghijlkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; |
2 |
|
3 |
function max_random_number(max) { |
4 |
return Math.floor(Math.random() * max); |
5 |
}
|
6 |
|
7 |
function get_random_string(length) { |
8 |
let random_string = ''; |
9 |
|
10 |
for(let i = 0; i < length; i++) { |
11 |
random_string += char_set[max_random_number(char_set.length - 1)]; |
12 |
}
|
13 |
|
14 |
return random_string; |
15 |
}
|
16 |
|
17 |
console.log(get_random_string(20)); |
18 |
// Outputs: lgtuRJZolu7AXj4HMoiM
|
19 |
|
20 |
console.log(get_random_string(40)); |
21 |
// outputs: scOoal3VXgeAjaHIieolhi2TyWFpAn5bBPPiX6UG
|
Usando toString()
para gerar string alfanumérica aleatória
Outra abordagem que podemos adotar para gerar sequências alfanuméricas aleatórias é usar o método toString()
método em nossos números gerados aleatoriamente. o toString()
O método retorna uma string que representa nosso valor numérico especificado. Este método aceita um opcional radix
parâmetro que especifica a base na qual você deseja representar o número. Um valor de 2 retornará uma string binária e um valor de 16 retornará uma string hexadecimal. O valor padrão deste parâmetro é 10. O valor máximo pode ser 36, pois abrange todos os 26 alfabetos e os 10 dígitos.
Aqui está a saída de algumas chamadas para este método para diferentes radix
valores:
1 |
let number = 3498650143868; |
2 |
|
3 |
console.log(number.toString(2)); |
4 |
// Outputs: 110010111010010111110011001000110001111100
|
5 |
|
6 |
console.log(number.toString(10)); |
7 |
// Outputs: 3498650143868
|
8 |
|
9 |
console.log(number.toString(16)); |
10 |
// Outputs: 32e97cc8c7c
|
11 |
|
12 |
console.log(number.toString(36)); |
13 |
// Outputs: 18n99yoak
|
Você deve ter notado que o comprimento da string de saída continua diminuindo à medida que aumentamos o radix
. No trecho de código a seguir, usaremos nosso max_random_number()
função da seção anterior para obter um número aleatório. Em seguida, converteremos esse número aleatório em uma string alfanumérica usando o toString()
método.
1 |
function max_random_number(max) { |
2 |
return Math.floor(Math.random() * max); |
3 |
}
|
4 |
|
5 |
for(let i = 0; i < 10; i++) { |
6 |
console.log(max_random_number(Number.MAX_SAFE_INTEGER).toString(36)); |
7 |
}
|
8 |
/* Outputs:
|
9 |
1tr84s6c2sl
|
10 |
1yj4varyoj7
|
11 |
1zdg9nn0z6r
|
12 |
lubrjj1zih
|
13 |
13tt2n5vw9t
|
14 |
1mv6sctjgf
|
15 |
yx3fhnznhf
|
16 |
1wj4mdcrqb9
|
17 |
26sir75af2r
|
18 |
qdv9xv800t
|
19 |
*/
|
E se você quiser strings alfanuméricas ainda maiores e quiser que elas tenham um comprimento fixo como 40 ou 100 caracteres? Nesse caso, podemos criar um loop que continua anexando nossas strings geradas até atingirmos o comprimento desejado.
1 |
function max_random_number(max) { |
2 |
return Math.floor(Math.random() * max); |
3 |
}
|
4 |
|
5 |
function get_random_string(length) { |
6 |
let random_string = ''; |
7 |
while(random_string.length < length) { |
8 |
random_string += max_random_number(Number.MAX_SAFE_INTEGER).toString(36); |
9 |
}
|
10 |
return random_string.substring(0, length); |
11 |
}
|
12 |
|
13 |
console.log(get_random_string(40)); |
14 |
// Outputs: bn0nfhcsjm18ylzqrm6bo1iktka2aq7qbbl5ybki
|
15 |
|
16 |
console.log(get_random_string(100)); |
17 |
// Outputs: rdosjhthsevmk91mj9zvqexz2z0v3pe2beasbzoworanzjg3bfpf975rzfy2fmo6pmj4p69u0x80ce92jh2vljx90g6r0lzd8vb0
|
Pensamentos finais
Neste tutorial, aprendemos como gerar números aleatórios e strings alfanuméricas em JavaScript. Gerar inteiros aleatórios é fácil em JavaScript com a ajuda de Math.random()
método. Tudo o que precisávamos fazer era dimensionar a saída para que correspondesse ao intervalo desejado. Você também pode considerar o uso do getRandomValues()
método se você quiser que seus números aleatórios sejam criptograficamente seguros.
Uma vez que sabemos como gerar números aleatórios, criar sequências alfanuméricas aleatórias é fácil. Tudo o que precisamos fazer é descobrir como converter nossos números em caracteres. Usamos duas abordagens aqui. O primeiro envolvia acessar os caracteres em um índice numérico aleatório em uma string predefinida. Essa técnica é útil se você quiser ser específico sobre os caracteres que devem ser incluídos nas sequências alfanuméricas aleatórias. A outra abordagem envolveu o uso de toString()
método para converter nossos números decimais para uma base diferente. Isso envolve menos ligações para o nosso max_random_number()
função.
Certamente existem muitas outras técnicas que você pode usar para gerar strings alfanuméricas aleatórias. Tudo depende de suas necessidades e de quão criativo você deseja ser com sua abordagem.