> pick | shuffle | pair <

// Cole uma lista, sorteie vencedores, embaralhe a ordem ou divida pessoas em grupos - tudo no seu navegador

[PICK_N]

Sortear N itens aleatórios

Sorteie qualquer número de vencedores da sua lista. Sem reposição para vencedores únicos, ou com reposição para sorteios em estilo ponderado.

[SHUFFLE]

Embaralhamento Fisher-Yates sem viés

Reordena a lista inteira com o clássico embaralhamento de Knuth. Cada permutação é igualmente provável - sem truques de ordenação ingênuos aqui.

[PAIRS]

Dividir em grupos

Divida uma lista em pares, trios ou qualquer tamanho de grupo. Perfeito para trabalho em dupla, rodízios de revisão de código ou sorteios de amigo secreto.

[SEEDED]

Reprodutibilidade com semente

Forneça uma string de semente para obter um sorteio determinístico. A mesma semente com a mesma lista sempre produz o mesmo resultado - compartilhável e verificável.

// SOBRE O SORTEADOR ALEATÓRIO

Como funciona:

Esta ferramenta usa o embaralhamento de Fisher-Yates (também conhecido como Knuth): percorra o array do último índice ao primeiro e, a cada passo, troque o elemento atual por um em um índice anterior escolhido de forma uniformemente aleatória. Isso produz uma permutação uniforme e sem viés em tempo O(n). O truque ingênuo array.sort(() => Math.random() - 0.5) é enviesado porque os comparadores de ordenação do JavaScript precisam ser transitivos - comparadores aleatórios violam isso e distorcem a distribuição. Para sorteios sem semente, obtemos entropia de window.crypto.getRandomValues. Quando você fornece uma string de semente, fazemos o hash dela com cyrb53 para um inteiro de 53 bits e então alimentamos um PRNG mulberry32 para que sementes idênticas produzam resultados idênticos e reproduzíveis.

Algoritmo:

for i = n-1 down to 1: j = randInt(0, i); swap(a[i], a[j]) - unbiased Fisher-Yates

Padrões e referências:

  • >Web Crypto API (W3C) - crypto.getRandomValues para aleatoriedade criptograficamente forte
  • >Embaralhamento de Fisher-Yates (1938), popularizado por Donald Knuth em The Art of Computer Programming Vol. 2
  • >mulberry32 - PRNG com semente pequeno, rápido e bem distribuído de Tommy Ettinger
  • >cyrb53 - hash de string de 53 bits de bryc, usado para transformar uma string de semente em um estado numérico do PRNG

Casos de uso comuns:

  • >Sorteios, rifas e escolha de um vencedor aleatório entre as inscrições
  • >Sorteios de nomes em sala de aula e seleção de alunos para perguntas surpresa
  • >Emparelhamento de equipes esportivas, treinos em dupla e chaves de torneio
  • >Atribuição de revisores de código em uma equipe de engenharia
  • >Seleção de amostras para testes A/B e coortes de pesquisa randomizadas
  • >Pares de amigo secreto, trocas de presentes e parceiros de almoço da equipe
  • >Entradas de teste aleatórias e sementes de fuzzing para QA
  • >Tomada de decisão em grupo e desempates
  • >Seleção de júri simulado e painéis de entrevista randomizados
  • >Sorteios em estilo loteria para eventos comunitários e prêmios

Ferramentas relacionadas:

  • >Gerador de números aleatórios — o complemento baseado em texto: sorteie números em um intervalo com as mesmas primitivas de reprodutibilidade com semente
  • >Gerador de UUID — identificadores v4 aleatórios quando você precisa de um ID opaco único em vez de um vencedor de uma lista
  • >Gerador de senhas — strings criptograficamente aleatórias com controle do conjunto de caracteres para tokens e credenciais
  • >randompickerwheel.app — interface de roda da sorte complementar a este sorteador de texto, perfeita para sorteios ao vivo diante do público, chamadas em sala de aula e revelações na tela

// EXEMPLOS DE SORTEIO

Sorteio — escolher 3 vencedores de 50 inscrições

> input:

alice@x.com
bob@x.com
carlos@x.com
…(50 linhas no total)

> config:

Modo=Pick N, Quantidade=3, Permitir duplicados=off, Semente=(vazia)

> output:

1. carlos@x.com
2. priya@x.com
3. wei@x.com

Embaralhar uma lista de 10 nomes para uma ordem de apresentação

> input:

Alice
Bob
Charlie
Dana
Evelyn
Farouk
Gabriela
Hiroshi
Isabella
Jamal

> config:

Modo=Shuffle, Semente=(vazia)

> output:

1. Hiroshi
2. Alice
3. Farouk
4. Jamal
5. Dana
6. Evelyn
7. Bob
8. Isabella
9. Gabriela
10. Charlie

Dividir uma turma de 12 alunos em grupos de 2

> input:

S01
S02
S03
S04
S05
S06
S07
S08
S09
S10
S11
S12

> config:

Modo=Pair Up, Tamanho do grupo=2, Semente=class-2026-05-02

> output:

Grupo 1: S07, S02
Grupo 2: S11, S04
Grupo 3: S09, S12
Grupo 4: S01, S06
Grupo 5: S03, S10
Grupo 6: S08, S05

Sorteio reproduzível com semente — execute duas vezes com a mesma semente, obtenha os mesmos vencedores

> input:

alpha
bravo
charlie
delta
echo
foxtrot
golf
hotel

> config:

Modo=Pick N, Quantidade=2, Semente=launch-day, Permitir duplicados=off

> output:

Execução 1: 1. echo
            2. bravo
Execução 2: 1. echo
            2. bravo  (idêntico — com semente)

// POR QUE O .SORT() INGÊNUO É ENVIESADO

Um embaralhamento de uma linha comum é arr.sort(() => Math.random() - 0.5). Parece elegante, cabe em uma linha e parece aleatório — mas a distribuição de permutações resultante está longe de ser uniforme. A especificação ECMAScript exige que as funções comparadoras sejam determinísticas e transitivas: se a < b e b < c, então a < c. Um comparador de cara ou coroa viola esse contrato, e a implementação de ordenação do motor visita os pares de comparação em um padrão não uniforme.

O V8 (Chrome, Node) usa Timsort; motores mais antigos usavam quicksort ou mergesort. Cada implementação visita um subconjunto diferente de pares de comparação e reutiliza as comparações em cache de maneiras diferentes. Como Mike Bostock demonstrou empiricamente (bost.ocks.org/mike/shuffle/compare.html), a ordenação ingênua produz saídas fortemente enviesadas em que algumas permutações aparecem várias vezes mais do que outras — inaceitável para um sorteio, um bucket A/B ou qualquer extração que precise ser justa.

O algoritmo correto é Fisher-Yates (embaralhamento de Knuth): percorra o array do último índice até o primeiro e, a cada passo, troque o elemento atual por um escolhido uniformemente ao acaso entre os índices 0..i. Ele roda em O(n), usa O(1) de espaço adicional e produz comprovadamente cada permutação com igual probabilidade.

// BAD: NOT uniformly random
const shuffled = arr.sort(() => Math.random() - 0.5);

// GOOD: Fisher-Yates (Knuth) shuffle
function shuffle(arr) {
  const a = arr.slice();
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

// IMPLEMENTE VOCÊ MESMO

Quer criar seu próprio sorteador ou auditar o nosso? Estas são as primitivas exatas que esta página usa — pequenas, sem dependências e idênticas ao que roda no seu navegador quando você clica em PICK. Copie-as diretamente para um script Node ou outro app web.

// Fisher-Yates shuffle (uniform, O(n))

function shuffle(arr, rng = Math.random) {
  const a = arr.slice();
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(rng() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

// Pick N without replacement (shuffle then slice)

function pickN(arr, n, rng = Math.random) {
  if (n > arr.length) {
    throw new Error('n exceeds list size');
  }
  return shuffle(arr, rng).slice(0, n);
}

// mulberry32 seeded PRNG + cyrb53 string hash

// cyrb53: turn a seed string into a 53-bit integer
function cyrb53(str, seed = 0) {
  let h1 = 0xdeadbeef ^ seed;
  let h2 = 0x41c6ce57 ^ seed;
  for (let i = 0, ch; i < str.length; i++) {
    ch = str.charCodeAt(i);
    h1 = Math.imul(h1 ^ ch, 2654435761);
    h2 = Math.imul(h2 ^ ch, 1597334677);
  }
  h1 = Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^
       Math.imul(h2 ^ (h2 >>> 13), 3266489909);
  h2 = Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^
       Math.imul(h1 ^ (h1 >>> 13), 3266489909);
  return 4294967296 * (2097151 & h2) + (h1 >>> 0);
}

// mulberry32: tiny seeded PRNG -> [0, 1)
function mulberry32(a) {
  return function () {
    a |= 0; a = (a + 0x6D2B79F5) | 0;
    let t = a;
    t = Math.imul(t ^ (t >>> 15), t | 1);
    t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
    return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
  };
}

// Build a seeded picker:
const h = cyrb53('my-seed', 1);
const state = (h ^ Math.floor(h / 4294967296)) >>> 0;
const rng = mulberry32(state);
const winners = pickN(['alice', 'bob', 'carlos'], 2, rng);

>> perguntas frequentes

P: Como a aleatoriedade é gerada?

R: Quando nenhuma semente é fornecida, usamos window.crypto.getRandomValues, o gerador de números aleatórios criptograficamente seguro do navegador, baseado na Web Crypto API. É a mesma fonte de entropia usada para chaves e tokens criptográficos, então é mais que robusta para rifas e embaralhamentos. Quando você fornece uma semente, derivamos de forma determinística um estado de 53 bits via o hash de string cyrb53 e o alimentamos em um PRNG mulberry32 para que o sorteio seja reproduzível.

P: Posso obter o mesmo resultado duas vezes usando uma semente?

R: Sim. Digite qualquer string no campo SEMENTE - uma data, o nome de um concurso, um hash, qualquer coisa. A mesma semente combinada com a mesma lista de entrada e o mesmo modo sempre produzirá exatamente a mesma saída. Isso é inestimável para sorteios transparentes em que você quer publicar a semente com antecedência e deixar os participantes verificarem o sorteio, ou para rodízios de engenharia que precisam ser reproduzíveis entre máquinas.

P: Qual é a diferença entre Pick N e Shuffle?

R: Pick N seleciona um subconjunto de tamanho N da sua lista, opcionalmente com reposição (duplicados permitidos). Shuffle retorna a lista inteira reordenada - nenhum item é descartado ou repetido, apenas reorganizado. Use Pick N quando quiser apenas alguns vencedores entre muitas inscrições; use Shuffle quando cada item ainda precisar participar, mas em uma nova ordem aleatória, como uma fila de apresentação ou playlist.

P: array.sort(() => Math.random() - 0.5) é realmente aleatório?

R: Não, é enviesado. A especificação ECMAScript exige que os comparadores de ordenação sejam determinísticos e transitivos (se a < b e b < c então a < c). Um comparador aleatório viola esse contrato, e diferentes motores JavaScript executam diferentes algoritmos de ordenação subjacentes (TimSort, mergesort, quicksort) que interagem com o comparador aleatório de maneiras diferentes. O resultado é uma distribuição não uniforme em que algumas permutações aparecem muito mais do que outras. Fisher-Yates é o algoritmo correto.

P: Posso formar pares de uma lista com número ímpar de itens?

R: Sim. O modo Pair Up embaralha sua lista com Fisher-Yates e depois a divide pelo tamanho de grupo escolhido. Se o total não dividir de forma exata, o último grupo será menor e é claramente rotulado como grupo restante na saída. Para uma lista ímpar, você pode aceitar uma entrada sozinha, aumentar o tamanho do grupo ou adicionar um nome de espaço reservado como "bye" antes do sorteio.

P: Minha lista é enviada para algum lugar?

R: Não. Esta ferramenta é 100% do lado do cliente - sua lista, sua semente e a saída nunca saem do seu navegador. Não há chamada ao servidor, nenhum registro e nenhuma análise sobre a entrada. Você pode se desconectar da internet depois de carregar a página e todos os botões continuam funcionando. Atualize a página e os dados somem para sempre.

P: Existe uma versão visual com roda da sorte desta ferramenta?

R: Para uma experiência interativa de roda de nomes com animação, efeitos sonoros e uma grande revelação visual, veja randompickerwheel.app. É um produto complementar focado em sorteios ao vivo diante do público e compartilhamento de tela. Esta página é um sorteador focado em texto, voltado para listas em massa, sorteios reproduzíveis com semente, exportação CSV e emparelhamento - útil quando você precisa de uma resposta determinística rápida em vez de uma apresentação.

// OTHER LANGUAGES