跳至主要內容

抽獎運作原理

我們不說空泛的「請相信我們很隨機」。以下是完整的演算法與機制。

中獎結果在轉盤轉動前就已確定

每次旋轉時,系統在動畫開始前就已先抽出中獎結果,接著才將轉盤動畫對準該目標。正是這種運作順序,確保了無論您用多大力道撥動轉盤,都絕不可能改變中獎結果;開啟「減少動態效果」時,也能在跳過動畫的同時執行完全相同的抽獎邏輯。這也代表您所看到的旋轉過程,只是忠實呈現一個早已確定的結果——這是同時落實上述兩項承諾的唯一方法。

隨機數的來源

我們的隨機來源是瀏覽器內建的密碼編譯級亂數產生器 crypto.getRandomValues,而非 Math.random。Math.random 允許被預測,且在部分引擎上的確具有規律性;這對抽獎的公正性至關重要。

為什麼我們要捨棄部分隨機數

若透過取餘數運算將 32 位元隨機整數轉換為「0 到 11 的數字」,會產生微小的偏差。因為 2³² 無法被 12 整除,前幾個選項會多出一次被抽中的機會。在十二等分的轉盤上,這種偏差雖然極小但真實存在,且永遠偏向特定扇區,無法透過次數增加而扯平。因此,我們不採用取餘數的做法,而是丟棄落在除不盡尾數區間的隨機數並重新抽取。這雖然偶爾需要多抽一次,卻能保證結果完全均勻公正。

const limit = Math.floor(2 ** 32 / max) * max;

let draw = crypto.getRandomValues(new Uint32Array(1))[0];
while (draw >= limit) {
  draw = crypto.getRandomValues(new Uint32Array(1))[0];
}

return draw % max;

權重機制:為什麼扇區大小與機率完全一致

在設定權重的抽獎中,系統會計算總權重,以相同的拒絕抽樣法在總數範圍內抽取均勻隨機數,並比對該數字落在哪個項目區間。轉盤隨後會嚴格依照各項目的權重比例繪製扇區面積。如果轉盤扇區看起來等大但機率不同,就是我們所反對的誤導行為;因此在我們的設計中,扇區面積與實際機率在架構上本質就是同一個數值。

您的清單絕不會離開您的瀏覽器

無需註冊帳號,也沒有伺服器端儲存空間。您的清單僅保存在此瀏覽器中,分享連結則是將轉盤資料直接編碼在網址內。我們完全無法查看,也不會記錄任何抽獎過程。

歡迎親自驗證

抽獎的核心程式碼僅有數十行,上述所有機制都有自動化測試嚴格把關——包括向產生器輸入專門觸發模數偏差(modulo bias)的數值,以確保結果依然維持均勻分佈。若有任何一項不符合承諾,測試就會立即報錯。

轉盤最多可容納 1000 個項目,無論是只有一個項目還是放滿 1000 個,採用的演算法完全一致。