
🎲 Hvordan generere et tilfeldig heltall i et intervall med JavaScript
Tilfeldige tall trengs overalt. Ordre-ID-er i nettbutikker, tilbakestillingskoder for passord, terningkast i nettleserspill, trekning av vinnere i konkurranser. Og nesten alltid skriver utviklere den samme linjen: Math.random().
Men mellom «få et tilfeldig desimaltall fra 0 til 1» og «få et tilfeldig heltall fra 5 til 20» ligger en kløft på tre operasjoner der nybegynnere jevnlig gjør feil: Math.floor og Math.ceil, pluss én eller ikke pluss, forvirring som fører til enten områdeoverskridelse eller ujevn fordeling.
La oss bryte ned formelen til siste parentes, skrive en fungerende generator i ren HTML+CSS+JS, og se på hvor Math.random() kommer til kort.
💡 Rask oversikt:
- Bryt ned formelen Math.floor(Math.random() * (max - min + 1)) + min, forstå hver operasjon.
- Lær hvorfor bare Math.floor fungerer, ikke Math.ceil eller Math.round, med eksempler på områdeforvrengninger.
- Kopier en ferdig HTML-generator: to felt, en knapp, resultatvisning, ren JS, ingen rammeverk.
- Mestre Crypto.getRandomValues når Math.random ikke er egnet og du trenger et kryptografisk sikkert alternativ.
Slik fungerer Math.random()
Math.random() er en statisk metode i det innebygde Math-objektet. Den tar ingen argumenter og returnerer et pseudotilfeldig flyttall i området [0, 1), ifølge MDN-spesifikasjonen. Hakeparentesen ved null betyr «inklusive», rundparentesen ved én betyr «eksklusive». Så du kan få 0.0, en verdi rundt 0.372, eller noe nær 0.999, men du får aldri nøyaktig 1.0.
Fordelingen er tilnærmet uniform. Implementasjonen er innebygd i motoren (V8, SpiderMonkey, JavaScriptCore), og utvikleren kan ikke velge eller tilbakestille den spesifikke algoritmen (vanligvis xorshift128+); frøet settes av motoren ved oppstart.
I seg selv er Math.random() ubrukelig for praktiske oppgaver. Spill trenger heltall, lotterier trenger heltall innenfor et område, kryptografi trenger kryptografisk sikker entropi som Math.random() mangler. Derfor pakkes alltid en områdekonverteringsformel rundt den.
Formelen: tilfeldig heltall i området [min, max]
Grunnformelen som dekker de aller fleste tilfeller innen webutvikling:
1 function randomInt(min, max) { 2 return Math.floor(Math.random() * (max - min + 1)) + min; 3 }
La oss bryte den ned med et læringseksempel der min = 5 og max = 10, basert på Math.random-dokumentasjonen:
- Anta at
Math.random()returnerte en verdiRi området [0, 1). max - min + 1=10 - 5 + 1=6, antallet mulige heltallsutfall: 5, 6, 7, 8, 9, 10.R * 6skalerte det tilfeldige desimaltallet til bredden av området.Math.floor(R * 6)rundet ned ved å forkaste desimaldelen. Nå har vi en indeks fra 0 til 5.index + minforskjøv medmin. Ferdig: et tilfeldig heltall fra og med 5 til og med 10.
Samme formel som en énlinjer:
1 const roll = Math.floor(Math.random() * (max - min + 1)) + min;
Hvorfor Math.floor, ikke Math.ceil eller Math.round
Valget av avrundingsmetode påvirker fordelingen kritisk. La oss demonstrere med et læringseksempel med området fra 1 til 3 (alle verdier unntatt intervallgrensene er beregnet). Tilnærmingen er beskrevet i det kanoniske StackOverflow-svaret.
Med Math.floor og formelen (max - min + 1):
- Hvis
Math.random()faller i den første tredjedelen av området [0, 1): multiplikasjon med 3 gir en verdi fra 0 til nesten 1,Math.floorforkaster desimaldelen, produserer indeks 0, plussmingir 1 (nøyaktig en tredjedel av tilfellene). - Hvis
Math.random()er i den midtre tredjedelen: multiplikasjon med 3 gir fra 1 til nesten 2,Math.floor→ indeks 1, plussmin→ 2 (en tredjedel til). - Hvis
Math.random()er i den siste tredjedelen: multiplikasjon med 3 gir fra 2 til nesten 3,Math.floor→ indeks 2, plussmin→ 3 (den siste tredjedelen).
Uniform fordeling.
Hva skjer med Math.ceil? Math.ceil(Math.random() * 3) gir 1, 2, 3, men 1 har en neglisjerbar sjanse (bare når Math.random() er nøyaktig 0, noe som nesten aldri skjer). Kantverdier forvrenges.
Math.round er også ikke-uniform: kantverdier får halvparten av sjansen sammenlignet med midtverdier. Derfor bruker generering av tilfeldige heltall utelukkende Math.floor.
Komplett eksempel: generator i HTML, CSS og JavaScript
En fungerende side du kan lagre som .html og åpne i en nettleser. To inndatafelt, en knapp, resultat på grønn bakgrunn.
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>
Koden er bevisst skrevet i ren JavaScript, uten rammeverk eller bundlere, slik at den kan kopieres og kjøres umiddelbart uten npm install. Funksjonen randomInt tar min og max, og returnerer et heltall inklusivt i begge ender. Knappebehandleren leser verdier fra feltene, validerer dem og viser resultatet.
Når Math.random() ikke er nok: Crypto.getRandomValues()
Math.random() er en pseudotilfeldig generator. Den er tilstrekkelig for spill, animasjoner, A/B-tester og valg av et tilfeldig array-element. Men for oppgaver der forutsigbarhet betyr sårbarhet, er den ikke egnet: tilbakestillingstoken for passord, API-nøkler, kryptografiske nonces, generatorer for engangslenker.
Tenk deg: du sender en bruker en lenke for tilbakestilling av passord med et token generert via Math.random(). Ved å kjenne frøet og algoritmen (som er standard for motoren), kan en angriper rekonstruere sekvensen og gjette tokenet. Det er nettopp derfor all sikkerhetsrelatert kode må bruke en kryptografisk sikker kilde til tilfeldighet.
For slike scenarioer finnes Web Crypto API: crypto.getRandomValues(). Den bruker operativsystemets kryptografisk sikre entropikilde og fyller den oppgitte typede arrayen med tilfeldige verdier.
Generering av et kryptografisk sikkert tilfeldig heltall i et område:
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 }
Dette bruker avvisningssampling: funksjonen ber om en tilfeldig 32-bits verdi og avviser de som faller utenfor det jevnt delbare området. Dette eliminerer modulo-bias, når noen verdier forekommer oftere enn andre.
I praksis er Math.random() tilstrekkelig for de fleste webapplikasjoner. Men hvis du skriver en generator for engangslenker eller bekreftelseskoder, bruk crypto.getRandomValues().
Video: generering av et tilfeldig tall i JavaScript
En kort demonstrasjon fra dcode-kanalen, som bryter ned Math.random() og områdeformelen med et live-eksempel i nettleserkonsollen:
⁉️🤔 Ofte stilte spørsmål
Inkluderer formelen Math.floor(Math.random() * (max - min + 1)) + min den øvre grensen?
Ja, det gjør den.
max - min + 1gir antallet mulige heltallsutfall, ogMath.floorkombinert med+ minsikrer atmaxer oppnåelig. For eksempel, medmin=1, max=3får du 1, 2 eller 3; alle tre verdiene er mulige.
Kan du bruke Math.ceil i stedet for Math.floor?
Teknisk sett ja, men fordelingen blir ikke-uniform. Med
Math.ceil(Math.random() * range)vil verdienminbare forekomme nårMath.random()returnerer nøyaktig 0, en forsvinnende sjelden hendelse.Math.floorgir hvert heltall i området lik sjanse, og derfor bruker standardformelen den.
Er Math.random() et virkelig tilfeldig tall?
Nei, det er et pseudotilfeldig tall. JavaScript-motoren bruker en deterministisk algoritme (vanligvis xorshift128+) som produserer en statistisk uniform sekvens, men å kjenne frøet tillater forutsigelse av alle påfølgende verdier. For kryptografi er dette uakseptabelt; bruk
crypto.getRandomValues().
Hvordan genererer du et tilfeldig flyttall i et område?
Fjern
Math.floorog+ 1:Math.random() * (max - min) + min. Dette gir et desimaltall framininklusivt tilmaxeksklusivt. Hvis du trenger den øvre enden inklusiv også, erstattmax - minmedmax - min + Number.EPSILON, men i praksis krever desimalområder sjelden inklusivitet for øvre grense.
Hva er raskest: Math.random() eller crypto.getRandomValues()?
Math.random()er størrelsesordener raskere. I V8-benchmarks når forskjellen et hundrefoldig gap eller mer, fordicrypto.getRandomValues()gjør et systemkall til/dev/urandom(Linux) eller tilsvarende, mensMath.random()er en ren PRNG i prosessen. For å generere tusenvis av verdier i en løkke, brukMath.random(); for et enkelt sikkerhetstoken, brukcrypto.getRandomValues().
Tilfeldig tall på 30 sekunder: hva du bør huske
Arbeidshesten er Math.floor(Math.random() * (max - min + 1)) + min. Husk tre regler: alltid Math.floor (ikke ceil, ikke round), alltid + 1 i multiplikatoren (slik at max er oppnåelig), alltid + min på slutten (for å forskyve området). Disse tre operasjonene dekker alt fra terningkast til å velge en tilfeldig vinner.
For tilbakestillingskoder og token for passord, bruk crypto.getRandomValues(). Tregere, men kryptografisk sikkert.
Hvis du bare vil prøve det ut, kopier HTML-eksempelet ovenfor, lagre det som en fil og åpne det i en nettleser. Ingen avhengigheter, ingen bundlere. Fungerer overalt der det finnes en <script>.



