最近接到一個需求,想在網站顯示虛構的線上人數。一般來說,顯示線上訪客數有很多免費的第三方服務,不過案主會有這樣的需求,代表網頁顯示的數字想要膨風一點。
用 JS 產生隨機數字其實很簡單,但如果隨機產生的線上人數太離譜,一眼就被看穿的話,對網站聲譽其實不太好,所以這功能也不是那麼簡單就做得出來。
(圖片出處: pixabay.com)
本篇說明大致的實現原理,未包含實作細節,不過提供的範例已經相當足夠了。
1. 隨機數字必須依照規則產生
首先頁面上顯示的線上人數,不可每次重新載入頁面就產生隨機數字。例如訪客進入首頁後,點進了一篇文章,相差不過幾秒,結果線上人數差異太大,很容易就被抓包。
若有人刻意測試連續重整頁面 5 次,結果看到 5 個不一樣的數字,一看就知道是造假。
所以這些隨機數字必須有個規則,例如在某特定時間內都是同樣的數字,假設能做到 5 分鐘內是同一個數字、下個 5 分鐘是另一個數字,這樣就成功了。
2. 限定數字區間
產生的數字也要有所限制,不能前 5 分鐘是 10 個人,下 5 分鐘是 1000 人,再來又變成 150 人,如此的劇烈變化。
能夠限定數字在某個小區間移動,例如 50 ~ 100,或是 25 ~ 50,都是相對比較合理的。
1. 偽隨機原理
原本隨機產生的數字每次都會不同,不過這篇「JS生成相同的随机数(伪随机数)」利用數學演算法,如果每次隨機數字的產生,是基於固定的一個「隨機種子」(seed),就有辦法產生相同的隨機數。
原理這篇有詳細的說明,數學上使用的方法稱為「線性同餘方法」,不過我們可以不用瞭解這麼多,直接拿公式來套就好了。
2. 偽隨機範例
以下修改自前述教學網頁提供的範例程式碼:
使用 seededRandom 函數可產生 0~1 之間的隨機數字,最後用一個迴圈連續跑 10 次隨機結果,你會發現無論執行多少次,這 10 個隨機數永遠一模一樣。
而當 seed 的值改變時,就會產生另外 10 組隨機數,這也代表隨機數永遠與 seed 數值連動。
以下提供一個簡單的範例:
參數修改請見註解說明,大致說明一下程式碼做了什麼事:
用 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 相關文章: