
🎲 Wie man eine zufällige ganze Zahl in einem Bereich mit JavaScript generiert
Zufallszahlen werden überall benötigt. Bestell-IDs in Onlineshops, Reset-Codes für Passwörter, Würfelwürfe in Browserspielen, die Auswahl von Gewinnspielteilnehmern. Und fast immer schreiben Entwickler dieselbe Zeile: Math.random().
Doch zwischen „eine zufällige Dezimalzahl von 0 bis 1 erhalten" und „eine zufällige Ganzzahl von 5 bis 20 erhalten" liegt ein Abgrund aus drei Operationen, bei denen Anfänger regelmäßig Fehler machen: Math.floor und Math.ceil, plus eins oder nicht plus eins, Verwirrung, die entweder zu Bereichsüberläufen oder zu ungleichmäßiger Verteilung führt.
Lassen Sie uns die Formel bis zur letzten Klammer zerlegen, einen funktionierenden Generator in reinem HTML+CSS+JS schreiben und uns ansehen, wo Math.random() an seine Grenzen stößt.
💡 Kurzüberblick:
- Zerlegung der Formel Math.floor(Math.random() * (max - min + 1)) + min, Verständnis jeder einzelnen Operation.
- Erfahren, warum nur Math.floor funktioniert, nicht Math.ceil oder Math.round, mit Beispielen für Bereichsverzerrungen.
- Kopieren eines fertigen HTML-Generators: zwei Felder, ein Button, Ergebnisausgabe, reines JS, keine Frameworks.
- Beherrschung von Crypto.getRandomValues, wenn Math.random nicht geeignet ist und Sie eine kryptografisch sichere Alternative benötigen.
Wie Math.random() funktioniert
Math.random() ist eine statische Methode des eingebauten Math-Objekts. Sie nimmt keine Argumente entgegen und gibt eine pseudozufällige Gleitkommazahl im Bereich [0, 1) zurück, gemäß der MDN-Spezifikation. Die eckige Klammer bei null bedeutet „einschließlich", die runde Klammer bei eins bedeutet „ausschließlich". Sie können also 0.0, einen Wert um 0.372 oder etwas nahe 0.999 erhalten, aber Sie werden niemals exakt 1.0 bekommen.
Die Verteilung ist annähernd gleichmäßig. Die Implementierung ist in der Engine (V8, SpiderMonkey, JavaScriptCore) eingebaut, und der Entwickler kann den spezifischen Algorithmus (meist xorshift128+) weder wählen noch zurücksetzen; der Startwert wird von der Engine beim Start gesetzt.
Für sich allein ist Math.random() für praktische Aufgaben nutzlos. Spiele brauchen Ganzzahlen, Lotterien brauchen Ganzzahlen innerhalb eines Bereichs, Kryptografie braucht kryptografisch sichere Entropie, die Math.random() nicht bietet. Deshalb wird immer eine Bereichsumrechnungsformel darumgelegt.
Die Formel: Zufällige Ganzzahl im Bereich [min, max]
Die grundlegende Formel, die die allermeisten Fälle in der Webentwicklung abdeckt:
1 function randomInt(min, max) { 2 return Math.floor(Math.random() * (max - min + 1)) + min; 3 }
Zerlegen wir sie anhand eines Lernbeispiels mit min = 5 und max = 10, basierend auf der Math.random-Dokumentation:
- Angenommen,
Math.random()gab einen WertRim Bereich [0, 1) zurück. max - min + 1=10 - 5 + 1=6, die Anzahl der möglichen ganzzahligen Ergebnisse: 5, 6, 7, 8, 9, 10.R * 6skalierte die zufällige Dezimalzahl auf die Breite des Bereichs.Math.floor(R * 6)rundete ab, indem der Nachkommateil verworfen wurde. Nun haben wir einen Index von 0 bis 5.index + minverschob ummin. Fertig: eine zufällige Ganzzahl von 5 bis einschließlich 10.
Dieselbe Formel als Einzeiler:
1 const roll = Math.floor(Math.random() * (max - min + 1)) + min;
Warum Math.floor, nicht Math.ceil oder Math.round
Die Wahl der Rundungsmethode beeinflusst die Verteilung entscheidend. Lassen Sie uns dies anhand eines Lernbeispiels mit dem Bereich von 1 bis 3 demonstrieren (alle Werte außer den Intervallgrenzen sind berechnet). Der Ansatz ist in der kanonischen StackOverflow-Antwort beschrieben.
Mit Math.floor und der Formel (max - min + 1):
- Fällt
Math.random()in das erste Drittel des Bereichs [0, 1): Multiplikation mit 3 ergibt einen Wert von 0 bis fast 1,Math.floorverwirft den Nachkommateil, erzeugt Index 0, plusminergibt 1 (exakt ein Drittel der Fälle). - Liegt
Math.random()im mittleren Drittel: Multiplikation mit 3 ergibt von 1 bis fast 2,Math.floor→ Index 1, plusmin→ 2 (ein weiteres Drittel). - Liegt
Math.random()im letzten Drittel: Multiplikation mit 3 ergibt von 2 bis fast 3,Math.floor→ Index 2, plusmin→ 3 (das letzte Drittel).
Gleichmäßige Verteilung.
Was passiert mit Math.ceil? Math.ceil(Math.random() * 3) ergibt 1, 2, 3, aber 1 hat eine verschwindend geringe Chance (nur wenn Math.random() exakt 0 ist, was fast nie vorkommt). Randwerte werden verzerrt.
Math.round ist ebenfalls ungleichmäßig: Randwerte erhalten die halbe Chance im Vergleich zu mittleren Werten. Deshalb verwendet die Ganzzahl-Zufallsgenerierung ausschließlich Math.floor.
Vollständiges Beispiel: Generator in HTML, CSS und JavaScript
Eine funktionierende Seite, die Sie als .html speichern und im Browser öffnen können. Zwei Eingabefelder, ein Button, Ergebnis auf grünem Hintergrund.
1 <!DOCTYPE html> 2 <html lang="ru"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Генератор случайных чисел</title> 6 <style> 7 body { 8 font-family: system-ui, sans-serif; 9 max-width: 400px; 10 margin: 50px auto; 11 padding: 0 16px; 12 } 13 label { 14 display: block; 15 margin-top: 12px; 16 font-weight: 600; 17 } 18 input { 19 width: 100%; 20 padding: 8px; 21 margin-top: 4px; 22 font-size: 16px; 23 box-sizing: border-box; 24 } 25 button { 26 margin-top: 16px; 27 padding: 10px 24px; 28 font-size: 16px; 29 cursor: pointer; 30 } 31 .result { 32 margin-top: 20px; 33 font-size: 24px; 34 font-weight: 700; 35 color: #2e7d32; 36 } 37 </style> 38 </head> 39 <body> 40 41 <h1>Случайное число в диапазоне</h1> 42 43 <label for="minInput">От:</label> 44 <input type="number" id="minInput" value="1"> 45 46 <label for="maxInput">До:</label> 47 <input type="number" id="maxInput" value="100"> 48 49 <button id="generateBtn">Сгенерировать</button> 50 51 <div class="result" id="resultDisplay"></div> 52 53 <script> 54 function randomInt(min, max) { 55 return Math.floor(Math.random() * (max - min + 1)) + min; 56 } 57 58 const minInput = document.getElementById('minInput'); 59 const maxInput = document.getElementById('maxInput'); 60 const generateBtn = document.getElementById('generateBtn'); 61 const resultDisplay = document.getElementById('resultDisplay'); 62 63 generateBtn.addEventListener('click', () => { 64 const min = parseInt(minInput.value, 10); 65 const max = parseInt(maxInput.value, 10); 66 67 if (isNaN(min) || isNaN(max)) { 68 resultDisplay.textContent = 'Введите оба числа'; 69 return; 70 } 71 if (min > max) { 72 resultDisplay.textContent = '«От» не может быть больше «До»'; 73 return; 74 } 75 76 const result = randomInt(min, max); 77 resultDisplay.textContent = `Результат: ${result}`; 78 }); 79 </script> 80 81 </body> 82 </html>
Der Code ist bewusst in reinem JavaScript geschrieben, ohne Frameworks oder Bundler, sodass er ohne npm install kopiert und sofort ausgeführt werden kann. Die Funktion randomInt nimmt min und max entgegen und gibt eine Ganzzahl zurück, die beide Enden einschließt. Der Button-Handler liest die Werte aus den Feldern, validiert sie und zeigt das Ergebnis an.
Wenn Math.random() nicht ausreicht: Crypto.getRandomValues()
Math.random() ist ein Pseudozufallsgenerator. Er genügt für Spiele, Animationen, A/B-Tests und die Auswahl eines zufälligen Array-Elements. Für Aufgaben jedoch, bei denen Vorhersagbarkeit eine Verwundbarkeit bedeutet, ist er nicht geeignet: Passwort-Reset-Tokens, API-Schlüssel, kryptografische Nonces, Generatoren für Einmallinks.
Stellen Sie sich vor: Sie senden einem Nutzer einen Passwort-Reset-Link mit einem Token, der via Math.random() generiert wurde. Kennt ein Angreifer den Startwert und den Algorithmus (die für die Engine standard sind), kann er die Sequenz rekonstruieren und das Token erraten. Genau deshalb muss jeder sicherheitsrelevante Code eine kryptografisch sichere Zufallsquelle verwenden.
Für solche Szenarien existiert die Web Crypto API: crypto.getRandomValues(). Sie nutzt die kryptografisch sichere Entropiequelle des Betriebssystems und füllt das übergebene typisierte Array mit Zufallswerten.
Erzeugung einer kryptografisch sicheren zufälligen Ganzzahl in einem Bereich:
1 function secureRandomInt(min, max) { 2 const range = max - min + 1; 3 const maxSafeVal = Math.floor(256 ** 4 / range) * range; 4 const buffer = new Uint32Array(1); 5 6 do { 7 crypto.getRandomValues(buffer); 8 } while (buffer[0] >= maxSafeVal); 9 10 return min + (buffer[0] % range); 11 }
Dies verwendet Rejection Sampling: Die Funktion fordert einen zufälligen 32-Bit-Wert an und verwirft jene, die außerhalb des gleichmäßig teilbaren Bereichs liegen. Dies beseitigt den Modulo-Bias, bei dem manche Werte häufiger vorkommen als andere.
In der Praxis genügt Math.random() für die meisten Webanwendungen. Wenn Sie jedoch einen Generator für Einmallinks oder Bestätigungscodes schreiben, verwenden Sie crypto.getRandomValues().
Video: Eine Zufallszahl in JavaScript generieren
Eine kurze Demonstration vom Kanal dcode, die Math.random() und die Bereichsformel mit einem Live-Beispiel in der Browser-Konsole zerlegt:
⁉️🤔 Häufig gestellte Fragen
Schließt die Formel Math.floor(Math.random() * (max - min + 1)) + min die obere Grenze ein?
Ja, das tut sie.
max - min + 1ergibt die Anzahl der möglichen ganzzahligen Ergebnisse, undMath.floorin Kombination mit+ minstellt sicher, dassmaxerreichbar ist. Mitmin=1, max=3erhalten Sie zum Beispiel 1, 2 oder 3; alle drei Werte sind möglich.
Kann man Math.ceil anstelle von Math.floor verwenden?
Technisch ja, aber die Verteilung wird ungleichmäßig. Bei
Math.ceil(Math.random() * range)tritt der Wertminnur dann auf, wennMath.random()exakt 0 zurückgibt, ein verschwindend seltenes Ereignis.Math.floorgibt jeder Ganzzahl im Bereich eine gleiche Chance, weshalb die Standardformel es verwendet.
Ist Math.random() eine echte Zufallszahl?
Nein, es ist eine Pseudozufallszahl. Die JavaScript-Engine verwendet einen deterministischen Algorithmus (meist xorshift128+), der eine statistisch gleichmäßige Sequenz erzeugt, aber die Kenntnis des Startwerts erlaubt die Vorhersage aller nachfolgenden Werte. Für Kryptografie ist dies inakzeptabel; verwenden Sie
crypto.getRandomValues().
Wie generiert man eine zufällige Gleitkommazahl in einem Bereich?
Entfernen Sie
Math.floorund+ 1:Math.random() * (max - min) + min. Dies ergibt eine Dezimalzahl vonmineinschließlich bismaxausschließlich. Wenn Sie das obere Ende ebenfalls einschließen müssen, ersetzen Siemax - mindurchmax - min + Number.EPSILON, aber in der Praxis erfordern Dezimalbereiche selten die Inklusivität der oberen Grenze.
Was ist schneller: Math.random() oder crypto.getRandomValues()?
Math.random()ist um Größenordnungen schneller. In V8-Benchmarks erreicht der Unterschied das Hundertfache oder mehr, weilcrypto.getRandomValues()einen Systemaufruf an/dev/urandom(Linux) oder Äquivalent tätigt, währendMath.random()ein rein prozessinterner PRNG ist. Für die Generierung tausender Werte in einer Schleife verwenden SieMath.random(); für ein einzelnes Sicherheits-Token verwenden Siecrypto.getRandomValues().
Zufallszahl in 30 Sekunden: Was man sich merken muss
Das Arbeitspferd ist Math.floor(Math.random() * (max - min + 1)) + min. Merken Sie sich drei Regeln: immer Math.floor (nicht ceil, nicht round), immer + 1 im Multiplikator (damit max erreichbar ist), immer + min am Ende (um den Bereich zu verschieben). Diese drei Operationen decken alles ab, vom Würfelwurf bis zur Auswahl eines zufälligen Gewinners.
Für Passwort-Reset-Codes und Tokens verwenden Sie crypto.getRandomValues(). Langsamer, aber kryptografisch sicher.
Wenn Sie es einfach ausprobieren möchten, kopieren Sie das obige HTML-Beispiel, speichern Sie es als Datei und öffnen Sie es in einem Browser. Keine Abhängigkeiten, keine Bundler. Funktioniert überall, wo es ein <script> gibt.



