2019年10月11日

Javascript 產生偽隨機數字的方法及應用

Javascript 產生偽隨機數字的方法及應用

Wayne Fu 0 A+
最近接到一個需求,想在網站顯示虛構的線上人數。一般來說,顯示線上訪客數有很多免費的第三方服務,不過案主會有這樣的需求,代表網頁顯示的數字想要膨風一點。

用 JS 產生隨機數字其實很簡單,但如果隨機產生的線上人數太離譜,一眼就被看穿的話,對網站聲譽其實不太好,所以這功能也不是那麼簡單就做得出來。

(圖片出處: pixabay.com)


一、設計原理


本篇說明大致的實現原理,未包含實作細節,不過提供的範例已經相當足夠了。

1. 隨機數字必須依照規則產生

首先頁面上顯示的線上人數,不可每次重新載入頁面就產生隨機數字。例如訪客進入首頁後,點進了一篇文章,相差不過幾秒,結果線上人數差異太大,很容易就被抓包。

若有人刻意測試連續重整頁面 5 次,結果看到 5 個不一樣的數字,一看就知道是造假。

所以這些隨機數字必須有個規則,例如在某特定時間內都是同樣的數字,假設能做到 5 分鐘內是同一個數字、下個 5 分鐘是另一個數字,這樣就成功了。


2. 限定數字區間

產生的數字也要有所限制,不能前 5 分鐘是 10 個人,下 5 分鐘是 1000 人,再來又變成 150 人,如此的劇烈變化。

能夠限定數字在某個小區間移動,例如 50 ~ 100,或是 25 ~ 50,都是相對比較合理的。



二、如何產生偽隨機數字


1. 偽隨機原理

原本隨機產生的數字每次都會不同,不過這篇「JS生成相同的随机数(伪随机数)」利用數學演算法,如果每次隨機數字的產生,是基於固定的一個「隨機種子」(seed),就有辦法產生相同的隨機數。

原理這篇有詳細的說明,數學上使用的方法稱為「線性同餘方法」,不過我們可以不用瞭解這麼多,直接拿公式來套就好了。


2. 偽隨機範例

以下修改自前述教學網頁提供的範例程式碼:

var seed = 5,
rnd;

function seededRandom(max, min) {
max = max || 1;
min = min || 0;
seed = (seed * 9301 + 49297) % 233280;
rnd = seed / 233280;
return min + rnd * (max - min);
}

for (var i = 0; i < 10; i++) {
console.log(seededRandom());
}

使用 seededRandom 函數可產生 0~1 之間的隨機數字,最後用一個迴圈連續跑 10 次隨機結果,你會發現無論執行多少次,這 10 個隨機數永遠一模一樣。

而當 seed 的值改變時,就會產生另外 10 組隨機數,這也代表隨機數永遠與 seed 數值連動。



三、隨機線上人數範例


以下提供一個簡單的範例:

var maxVisitors = 100, // 最大訪客數
minVisitors = 50, // 最小訪客數
today = new Date(),
year = today.getFullYear(),
month = today.getMonth() + 1,
hour = today.getHours(),
minute = today.getMinutes(),
second = today.getSeconds(),
seed, visitors;

// 每 30 秒產生一個線上人數
if (second >= 0 && second < 30) {
seed = year * month * hour * minute * 1;
} else {
seed = year * month * hour * minute * 31;
}
visitors = seededRandom(maxVisitors, minVisitors);
alert(visitors);
function seededRandom(max, min) {
seed = (seed * 9301 + 49297) % 233280;
var rnd = seed / 233280;
return Math.round(min + rnd * (max - min));
}

參數修改請見註解說明,大致說明一下程式碼做了什麼事:
  • 限定產生 50 ~ 100 之間的隨機數
  • 每分鐘 0 ~ 29 秒之間產生的隨機數一樣,每分鐘 30 ~ 59 秒之間產生的隨機數也一樣。
  • 可以快速不斷執行這段程式碼,會發現每過 30 秒才產生新的隨機數


更多 Javascript 相關文章:
0 0
如這篇文章對你有幫助,歡迎「分享」到 FB、「追蹤」粉絲團、「訂閱」最新文章

2 則留言:

  1. if (second >= 0 & second < 30) 似乎應使用 &&

    回覆刪除

張貼留言注意事項:

◎ 勾選「通知我」可收到後續回覆的mail!
◎ 請在相關文章留言,與文章無關的主題可至「Blogger 社團」提問。
◎ 提問若無法提供足夠的資訊供判斷,可能會被無視。建議先參考這篇「Blogger 提問技巧及注意事項」。
◎ CSS 相關問題非免費諮詢,建議使用「Chrome 開發人員工具」尋找答案。
◎ 手機版相關問題請參考「Blogger 行動版範本的特質」→「三、行動版範本不一定能執行網頁版工具」。
◎ 非官方範本問題、或貴站為商業網站,請參考「Blogger 免費諮詢 + 付費諮詢
◎ 若是使用官方 RWD 範本,請參考「Blogger 推出全新自適應 RWD 官方範本及佈景主題」→ 不建議對範本進行修改!
◎ 若留言要輸入語法,"<"、">"這兩個符號請用其他符號代替,否則語法會消失!
◎ 為了過濾垃圾留言,所有留言不會即時發佈,請稍待片刻。
◎ 本站「已關閉自刪留言功能」。

TOP