> pick | shuffle | pair <

// Collez une liste, tirez des gagnants, mélangez l'ordre ou répartissez les personnes en groupes - le tout dans votre navigateur

[PICK_N]

Tirer N éléments au hasard

Tirez n'importe quel nombre de gagnants de votre liste. Sans remise pour des gagnants uniques, ou avec remise pour des tirages de type pondéré.

[SHUFFLE]

Mélange Fisher-Yates non biaisé

Réordonne toute la liste avec le classique mélange de Knuth. Chaque permutation est également probable - aucune astuce de tri naïf ici.

[PAIRS]

Répartir en groupes

Divisez une liste en paires, trios ou n'importe quelle taille de groupe. Parfait pour le travail en binôme, les rotations de revue de code ou les tirages de Père Noël secret.

[SEEDED]

Reproductibilité par graine

Fournissez une chaîne de graine pour obtenir un tirage déterministe. La même graine plus la même liste produit toujours le même résultat - partageable et vérifiable.

// À PROPOS DU TIRAGE AU SORT

Fonctionnement:

Cet outil utilise le mélange de Fisher-Yates (alias Knuth) : parcourez le tableau du dernier indice au premier et, à chaque étape, échangez l'élément courant avec un élément situé à un indice antérieur choisi uniformément au hasard. Cela produit une permutation uniforme non biaisée en temps O(n). L'astuce naïve array.sort(() => Math.random() - 0.5) est biaisée car les comparateurs de tri JavaScript doivent être transitifs - les comparateurs aléatoires violent cette règle et faussent la distribution. Pour les tirages sans graine, nous tirons l'entropie de window.crypto.getRandomValues. Lorsque vous fournissez une chaîne de graine, nous la hachons avec cyrb53 en un entier de 53 bits, puis nous alimentons un PRNG mulberry32 afin que des graines identiques produisent des résultats identiques et reproductibles.

Algorithme:

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

Normes & références:

  • >Web Crypto API (W3C) - crypto.getRandomValues pour un aléa cryptographiquement fort
  • >Mélange de Fisher-Yates (1938), popularisé par Donald Knuth dans The Art of Computer Programming Vol. 2
  • >mulberry32 - PRNG à graine petit, rapide et bien distribué par Tommy Ettinger
  • >cyrb53 - hachage de chaîne 53 bits par bryc, utilisé pour transformer une chaîne de graine en état numérique de PRNG

Cas d'usage courants:

  • >Jeux-concours, tombolas et désignation d'un gagnant aléatoire parmi les participations
  • >Tirages de noms en classe et sélection d'élèves à interroger
  • >Appariement d'équipes sportives, entraînements en binôme et tableaux de tournoi
  • >Affectation des relecteurs de revue de code au sein d'une équipe d'ingénierie
  • >Sélection d'échantillons de tests A/B et cohortes de sondage randomisées
  • >Paires de Père Noël secret, échanges de cadeaux et binômes de déjeuner d'équipe
  • >Entrées de test aléatoires et graines de fuzzing pour la QA
  • >Prise de décision en groupe et départage des égalités
  • >Sélection de jury fictif et panels d'entretien randomisés
  • >Tirages de type loterie pour des événements communautaires et des lots

Outils connexes:

  • >Générateur de nombres aléatoires — le complément textuel : tirez des nombres dans une plage avec les mêmes primitives de reproductibilité par graine
  • >Générateur d'UUID — identifiants v4 aléatoires lorsque vous avez besoin d'un identifiant opaque unique plutôt que d'un gagnant tiré d'une liste
  • >Générateur de mots de passe — chaînes cryptographiquement aléatoires avec contrôle du jeu de caractères pour les jetons et identifiants
  • >randompickerwheel.app — interface de roue de la fortune complémentaire à ce sélecteur textuel, parfaite pour les tirages devant un public en direct, les interrogations en classe et les révélations à l'écran

// EXEMPLES DE TIRAGES

Jeu-concours — tirer 3 gagnants parmi 50 participations

> input:

alice@x.com
bob@x.com
carlos@x.com
…(50 lignes au total)

> config:

Mode=Pick N, Nombre=3, Autoriser les doublons=off, Graine=(vide)

> output:

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

Mélanger une liste de 10 noms pour un ordre de présentation

> input:

Alice
Bob
Charlie
Dana
Evelyn
Farouk
Gabriela
Hiroshi
Isabella
Jamal

> config:

Mode=Shuffle, Graine=(vide)

> output:

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

Répartir une classe de 12 élèves en groupes de 2

> input:

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

> config:

Mode=Pair Up, Taille du groupe=2, Graine=class-2026-05-02

> output:

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

Tirage reproductible avec graine — exécutez deux fois avec la même graine, obtenez les mêmes gagnants

> input:

alpha
bravo
charlie
delta
echo
foxtrot
golf
hotel

> config:

Mode=Pick N, Nombre=2, Graine=launch-day, Autoriser les doublons=off

> output:

Exécution 1: 1. echo
             2. bravo
Exécution 2: 1. echo
             2. bravo  (identique — graine)

// POURQUOI .SORT() NAÏF EST BIAISÉ

Un mélange en une ligne courant est arr.sort(() => Math.random() - 0.5). Il semble élégant, tient en une ligne et paraît aléatoire — mais la distribution des permutations résultantes est loin d'être uniforme. La spécification ECMAScript exige que les fonctions de comparaison soient déterministes et transitives : si a < b et b < c, alors a < c. Un comparateur à pile ou face viole ce contrat, et l'implémentation de tri du moteur visite les paires de comparaison selon un motif non uniforme.

V8 (Chrome, Node) utilise Timsort ; les moteurs plus anciens utilisaient quicksort ou mergesort. Chaque implémentation visite un sous-ensemble différent de paires de comparaison et réutilise les comparaisons mises en cache de différentes manières. Comme l'a démontré empiriquement Mike Bostock (bost.ocks.org/mike/shuffle/compare.html), le tri naïf produit des sorties fortement biaisées où certaines permutations apparaissent plusieurs fois plus souvent que d'autres — inacceptable pour un jeu-concours, un compartiment A/B ou tout tirage devant être équitable.

Le bon algorithme est Fisher-Yates (mélange de Knuth) : parcourez le tableau du dernier indice jusqu'au premier et, à chaque étape, échangez l'élément courant avec un élément choisi uniformément au hasard parmi les indices 0..i. Il s'exécute en O(n), utilise un espace supplémentaire O(1) et produit de façon prouvée chaque permutation avec une probabilité égale.

// 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;
}

// IMPLÉMENTEZ-LE VOUS-MÊME

Vous voulez créer votre propre sélecteur ou auditer le nôtre ? Voici les primitives exactes que cette page utilise — petites, sans dépendance et identiques à ce qui s'exécute dans votre navigateur lorsque vous cliquez sur PICK. Copiez-les directement dans un script Node ou une autre application 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);

>> questions fréquentes

Q : Comment l'aléa est-il généré ?

R : Lorsqu'aucune graine n'est fournie, nous utilisons window.crypto.getRandomValues, le générateur de nombres aléatoires cryptographiquement sûr du navigateur basé sur la Web Crypto API. C'est la même source d'entropie que celle utilisée pour les clés et jetons cryptographiques, donc largement assez robuste pour les tombolas et les mélanges. Lorsque vous fournissez une graine, nous dérivons de façon déterministe un état de 53 bits via le hachage de chaîne cyrb53 et l'injectons dans un PRNG mulberry32 afin que le tirage soit reproductible.

Q : Puis-je obtenir le même résultat deux fois avec une graine ?

R : Oui. Saisissez n'importe quelle chaîne dans le champ GRAINE - une date, un nom de concours, un hachage, n'importe quoi. La même graine combinée à la même liste d'entrée et au même mode produira toujours exactement la même sortie. C'est précieux pour les jeux-concours transparents où vous souhaitez publier la graine à l'avance et laisser les participants vérifier le tirage, ou pour les rotations d'ingénierie qui doivent être reproductibles d'une machine à l'autre.

Q : Quelle est la différence entre Pick N et Shuffle ?

R : Pick N sélectionne un sous-ensemble de taille N dans votre liste, éventuellement avec remise (doublons autorisés). Shuffle renvoie la liste entière réordonnée - aucun élément n'est supprimé ni répété, simplement réarrangé. Utilisez Pick N lorsque vous ne voulez que quelques gagnants parmi de nombreuses participations ; utilisez Shuffle lorsque chaque élément doit encore participer mais dans un nouvel ordre aléatoire, comme une file d'attente de présentation ou une playlist.

Q : array.sort(() => Math.random() - 0.5) est-il vraiment aléatoire ?

R : Non, c'est biaisé. La spécification ECMAScript exige que les comparateurs de tri soient déterministes et transitifs (si a < b et b < c alors a < c). Un comparateur aléatoire viole ce contrat, et différents moteurs JavaScript exécutent différents algorithmes de tri sous-jacents (TimSort, mergesort, quicksort) qui interagissent avec le comparateur aléatoire de différentes manières. Le résultat est une distribution non uniforme où certaines permutations apparaissent bien plus souvent que d'autres. Fisher-Yates est l'algorithme correct.

Q : Puis-je former des paires à partir d'une liste de taille impaire ?

R : Oui. Le mode Pair Up mélange votre liste avec Fisher-Yates puis la découpe selon la taille de groupe choisie. Si le total ne se divise pas équitablement, le dernier groupe sera plus petit et clairement étiqueté comme groupe restant dans la sortie. Pour une liste impaire, vous pouvez accepter une entrée seule, augmenter la taille du groupe ou ajouter un nom de remplacement comme "bye" avant le tirage.

Q : Ma liste est-elle téléversée quelque part ?

R : Non. Cet outil est 100 % côté client - votre liste, votre graine et la sortie ne quittent jamais votre navigateur. Il n'y a aucun appel serveur, aucune journalisation et aucune analyse de l'entrée. Vous pouvez vous déconnecter d'Internet après le chargement de la page et chaque bouton continue de fonctionner. Actualisez la page et les données disparaissent définitivement.

Q : Existe-t-il une version visuelle en roue de la fortune de cet outil ?

R : Pour une expérience interactive de roue de noms avec animation, effets sonores et grande révélation visuelle, voir randompickerwheel.app. C'est un produit complémentaire axé sur les tirages devant un public en direct et le partage d'écran. Cette page est un sélecteur textuel d'abord, axé sur les listes en masse, les tirages reproductibles avec graine, l'export CSV et l'appariement - utile lorsque vous avez besoin d'une réponse déterministe rapide plutôt que d'une présentation.

// OTHER LANGUAGES