JavaScript 提供了兩種實際的方式來產生隨機數:內建的 Math.random(),會回傳位於半開放區間 [0, 1) 的浮點數;以及瀏覽器的 Crypto.getRandomValues() 方法,會從作業系統取得密碼學強度足夠的整數,填入一個型別陣列。這兩個函式都無法直接開箱即用地在自訂的含端點整數區間中回傳可用的整數,因此大多數的正式環境程式碼會將原始輸出套上一個映射步驟,將數值放大、取整數(floor),並調整位移。在 min 到 max 之間產生整數最常見的寫法是 Math.floor(Math.random() * (max - min + 1)) + min,但若在那個寫法上再直接套上取模(modulo),只要隨機區間無法被目標區間整除,就會產生偏誤。若要取得無偏誤的抽樣,最乾淨的做法是拒絕抽樣(rejection sampling):先從 Web Crypto 取得一個 32 位元的值,丟棄落在不完整尾段中的任何值,僅接受其餘的值,再將它映射到所要求的含端點區間中。像 Random Number Generator 這樣的本地瀏覽器工具也採用相同的技術,讓你無需自行撰寫任何 JavaScript,就能抽取最多 1,000 個含端點的整數。

JavaScript 產生隨機值的兩種方法
JavaScript 內建的隨機來源是 Math.random(),它是 Math 物件上的一個靜態方法,會回傳一個大於或等於 0 且嚴格小於 1 的浮點偽隨機數。這個值是由 JavaScript 引擎使用基於種子的演算法所產生;ECMAScript 規格僅要求輸出在統計上看起來是隨機的,並不要求不可預測。這使得 Math.random() 適合用於遊戲、UI 變化、範例資料與一般抽樣,但不適用於安全性權杖、密碼,或任何不應讓攻擊者重現輸出的情境。
另一個選項位於瀏覽器所公開的全域 Crypto 物件上:crypto.getRandomValues(),定義於 W3C Web Cryptography API。你需要傳入一個型別陣列,例如 Uint32Array 或 Uint8Array,瀏覽器就會使用來自作業系統密碼學熵源的隨機位元來填入陣列。位於 https://www.w3.org/TR/WebCryptoAPI/#Crypto-method-getRandomValues 的 W3C 規格,以及位於 MDN's getRandomValues documentation 的 MDN 參考文件,皆描述了相同的契約:回傳的值在該型別陣列的範圍內呈均勻分布。唯一的限制是這個函式是以陣列為基礎,所以你必須自行從緩衝區中讀出數字。
| 屬性 | Math.random() | Crypto.getRandomValues() |
|---|---|---|
| 輸出類型 | 位於 [0, 1) 的數字 | 填入型別陣列的整數 |
| 隨機性來源 | 引擎內部的偽隨機產生器 | 作業系統的密碼學熵 |
| 是否適用於安全性用途 | 否 | 是,依據 W3C 規格 |
| 範圍控制 | 無內建;需自行縮放與取整數 | 無內建;需自行縮放、遮罩或拒絕 |
| 瀏覽器支援 | 於瀏覽器中廣泛可用 | 於現代瀏覽器中廣泛可用,但需在安全情境下 |
使用 Math.random 建立含端點的整數區間
要在 JavaScript 中以最簡單的方式產生一個從 min 到 max 含端點的整數,需要結合三個運算:相乘、取整數(floor)、以及位移。整個運算式寫成一行:const n = Math.floor(Math.random() * (max - min + 1)) + min;
這個運算式分三個階段運作。首先,(max - min + 1) 計算出含端點區間中的整數個數。其次,乘以 Math.random() 會將該數量縮放為位於 [0, count) 的浮點數。第三,Math.floor 將浮點數截斷為整數位移,再加到 min 上。以 min = 1 與 max = 10 為例,公式會化為 Math.floor(Math.random() * 10) + 1;若 Math.random() 回傳 0.4732,結果就是 Math.floor(4.732) + 1 = 4 + 1 = 5。這條簡單的算術鏈,就是你在 JavaScript 中取得含端點整數所需的全部寫法。
將相同的模式包裝成可重複使用的函式,就會變成 function randomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; }。呼叫一次即可取得單一值,或在迴圈中呼叫以取得一批值。每次抽樣都是獨立的,因此在區間較小時,同一個數字有可能連續出現兩次——而這正好是擲骰子、可重複抽樣,或重複實驗所期望的行為。
- 決定你的含端點最小值與最大值;若兩個端點與含端點區間大小皆落在 JavaScript 的安全整數範圍內,則支援負數邊界。
- 呼叫 Math.random() 取得位於 [0, 1) 的均勻浮點數。
- 將結果乘以 (max - min + 1),將其縮放為區間中的整數個數。
- 套用 Math.floor() 捨棄小數部分,以產生整數位移。
- 加上 min,使位移從下界(而非從零)開始。
- 儲存或輸出該整數;如需額外的獨立抽樣,請再次呼叫該函式。
取模映射如何扭曲區間抽樣
一個常見的捷徑是 Math.floor(Math.random() * max) % range,或是它的 Web Crypto 變形——拉取一個 32 位元的字並寫成 word % range。兩者乍看之下都正確,但只要隨機區間不是目標區間的整數倍,就會產生偏誤。想像將一個四面的隨機輸出投射到三面的目標上:值 0 與 1 會乾淨地對應到 0 與 1,但值 2 與 3 都會塌縮到 2,使得 2 出現的機會加倍。經過數千次抽樣後,這種扭曲會變得明顯;而任何無法被 2 的冪次整除的小區間,都是脆弱的。
修正方法是拒絕抽樣。產生器先拉取一個原始值,檢查它是否落在模數範圍頂端的不完整尾段中,若落在該處便予以拒絕;只有與目標位置一對一對應的值才會被接受。每個被接受的整數擁有相同數量的可能原始值,因此最終分布是均勻的。同樣的技巧可透過擴大原始池,並拒絕任何大於或等於來源範圍內最大目標區間整數倍數的值,來應用於更大的區間。這就是為什麼一個實作良好的隨機整數產生器絕不會僅依賴單一的取模步驟。
無需撰寫程式碼即可在 JavaScript 中產生隨機數
對於希望取得相同無偏誤行為,但不想自行撰寫輔助函式的讀者,Random Number Generator 會在當前瀏覽器中執行,於 Web Crypto 之上套用拒絕抽樣,並且絕不會將邊界或結果傳送至伺服器。無論你需要單一值或一批值,工作流程都是相同的三個步驟,輸出則是一個簡單的逗號分隔清單,你可以直接複製到其他程式中。
- 輸入最小與最大的安全整數;兩個端點皆可能出現在輸出中,且在含端點區間大小本身為安全整數時,允許使用負數邊界。
- 選擇介於 1 與 1,000 之間的結果數量,然後決定此次抽樣是否允許重複的數字。
- 選擇 Generate numbers 並檢視以逗號分隔的清單,你可以一次選取並複製。
更改任何輸入都會清除先前的清單,因此畫面上的輸出永遠反映當前設定。若你要求的唯一值數量超過區間所能容納的數量——例如在 1 到 3 中抽取 5 個唯一值——產生器會將該請求回報為不可能,而非默默回傳一份較短的清單。對於空白欄位、上下界顛倒、小數、無限大,以及超出 JavaScript 安全整數範圍的不安全整數,輸入同樣會被拒絕,使錯誤得以直接顯示,而非隱藏在經過四捨五入的邊界之後。
選擇正確的區間設定
重複選項會改變演算法,但不會改變底層的隨機性。啟用重複時,每次抽樣皆為獨立,因此同一個數字可能出現多次——這是重複模擬、擲骰子,或任何先前的結果仍應保留抽樣資格之實驗的正確選擇。停用重複時,則會使用稀疏的部分 Fisher-Yates 洗牌,以 O(count) 的記憶體挑選唯一偏移,因此從 1 到 100 中選取 10 個相異值時,會產生 10 個不同的整數而不會重複——這適用於抽獎、樣本選取,或編號參加者的排序。
1,000 筆結果的上限是基於記憶體與清晰度的保護機制,並非試圖成為一套完整的稽核工具。較大的任務應拆分為多個批次處理;而任何具有重要後果的抽樣——包括受規範的抽獎、安全性權杖,或存取控制決策——皆應遵循貴組織的稽核程序。此產生器刻意不公開種子、已簽署的逐字記錄,或外部隨機性信標,因此訪客無法於事後證明是哪一份瀏覽器熵產生了特定清單。它的設計目的是用於課堂活動、抽獎、隨機化測試資料、排序選擇,以及遊戲設定;在這些情境中,方便性與均勻分布比密碼學可驗證性更為重要。
| 重複設定 | 使用時機 | 範例 |
|---|---|---|
| 啟用(可重複) | 重複模擬、擲骰子、先前結果仍保留抽樣資格的抽樣 | 從 1 到 6 抽 5 次,相同的數字可能出現兩次 |
| 停用(不重複) | 選取相異位置、識別編號、編號參加者、隨機排序 | 從 1 到 20 抽 5 個唯一值,會產生 5 個不同的整數 |
| 數量等於區間大小且關閉重複 | 為區間中的每個整數產生唯一的隨機排序 | 將 count 設為 10、min 設為 1、max 設為 10,以取得完整的排列 |
Where These Random Numbers Are Useful
The same unbiased integer generator covers a wide spread of everyday tasks. Classroom teachers pull student numbers for cold-call questions, small businesses draw raffle winners for internal events, QA engineers seed randomized test data without writing a fixture, board-game hosts roll initiative order, and writers or game masters randomize loot tables or NPC choices. None of those uses requires cryptographic randomness, but all of them benefit from a uniform distribution so that no slot in the range is favored over another.
For tasks that need a different surface, such as picking a name from a typed list, spinning a wheel, rolling multiple dice at once, or generating a coin flip, the linked tools below handle each shape directly. Pair them with the Random Number Generator whenever you need a controlled integer range rather than a name, a die face, or a yes or no decision, so that each tool stays focused on the shape of randomness you actually need.
- Random Name Picker Wheel — pick a random winner from a typed list with a fair spin.
- Dice Roller — roll d4 through d20 or any custom die without keeping physical pieces.
- Coin Flip — flip a fair virtual coin powered by the same browser Web Crypto source.
For readers who want the same numeric approach in another language or sheet, the practical guides below walk through the equivalent recipes in C++ and Excel so the pattern can be ported without rewriting the algorithm from scratch.
- How to Generate Random Numbers in C++ (Quick Guide) — translate the same pattern into std::uniform_int_distribution.
- Generate Random Numbers in Excel Within a Range (3 Ways) — use RANDBETWEEN and related functions inside a spreadsheet.