一般用戶、玩家在使用線上服務時, 經常會碰到需要產生隨機值的流程, 例如抽獎、線上遊戲抽卡...等. 以往的隨機值產生結果通常是由後端工程人員撰寫的程式碼產生出來的, 基本上您無法驗證這個隨機的結果是否真實, 且伺服器端是可作弊的.
以丁特的例子來說, 抽遊戲裝備材料的機率官方有公佈, 但玩家大量抽取後, 計算出的機率與官方公佈的機率相差甚遠, 導致玩家無法完全信任官方所產生出來的結果, 但若使用此流程產生隨機值的話, 就可以清楚知道官方是否作弊, 還是您真的臉黑
這裡提供了最佳解決方案, 讓隨機值的結果是可被驗證的, 並確保服務端與客戶端雙方都無法作弊, 我們提供了簡單的小工具, 讓您可以驗證您的隨機值相關資訊(前提是服務端必須使用這個驗證流程撰寫程式)
以下由我來為您解釋此流程
如何證明公平性?
可驗證的隨機值有很多種方式可以實現, 也有很多種不同的加密、散列演算法可以使用
我們這裡使用的散列方式有 sha256
、
hmac-sha512
總共會有以下幾個組成因素, 每次隨機值產生前皆有不同的值
在您產生隨機值之前, 服務端會先將 服務端序號
經過 sha256
加密後提供給您,
這邊很重要, 因為您是提前先知道這個以加密的 服務端序號
, 所以服務端是無法更改原始的(未加密的) 服務端序號
, 否則事後會被發現作弊, 再加上 sha256
散列演算法的特性,
您無法算出尚未散列加密的原始字串值, 所以您也無法作弊, 為什麼會這樣呢? 讓我們繼續看下去...
接著在您的客戶端, 產生一組 客戶端序號
, 您在產生隨機值之前, 都可以任意更改此序號內容, 假設目前是我們第一次要產生隨機值,
我們客戶端也將隨機值設為數字 1 (此隨機值只要單次請求不重複即可), 這個 客戶端序號
可以讓客戶自己決定內容值
客戶端發出產生隨機值的請求, 將客戶端的 客戶端序號
與 隨機值
(nonce)
一起發給服務端
服務端收到您的請求後, 執行散列計算, 函數與參數為 hmac-sha512(服務端序號, 客戶端序號-隨機值), 執行後將產生我們要的隨機值, 完成後, 將此隨機值與服務端原始的(未加密的) 服務端序號
提供給客戶端做呈現, 此時客戶端可以用此未加密的 服務端序號
進行
sha256
散列計算, 還記得客戶端一開始就獲得了服務端提供的一串(已加密) 服務端序號
嗎? 此時將此兩個已加密的序號做比對, 若值相同, 表示此隨機值的結果是公平的, 服務端確實使用一開始就設定好的 服務端序號
來產生隨機值, 若不同, 則表示服務端作弊.
這樣就完成了一次的隨機值產生過程, 以下我們來為技術人員舉個簡單的例子
技術舉例
隨機值產生前, 服務端產生了一個 服務端序號
(由您自行產生不同的值):
serverseed
並將此序號在伺服器端進行 sha256 散列, 得出結果:
5eb59053dcb5810322e367245f631a65589ddf7bbe950d2986a43a5f376312ef
(請先將這個 hash 結果提供給客戶端)
在客戶端程式碼中產生一個隨機的 客戶端序號
(用戶可任意更改):
我真的很棒
在客戶端程式碼產生一個 隨機值
(送至服務端時, 需檢查不重複):
1
將客戶端的 客戶端序號
與 隨機值
送至服務端後, 進行以下工作:
hmac-sha512(服務端序號,
客戶端序號-隨機值)
像是這樣
hmac-sha512("serverseed",
"我真的很棒-1")
得出了隨機值的結果為:
6b2e3b51597dd4626c62e65af64ae43c01a1a1d1b2a6b6c857627588dde5dbf99118547935cf101e641f38e0d855b8c207d8ed07d15a007a1c566f0130277868
我們再拿此隨機值結果做應用, 記得將此結果與 服務端序號
(原始未加密的), 返回給客戶端, 提供此資訊可以讓客戶端進行驗證, 並信任此隨機值
應用方式很多, 可以將此字串的前面幾個字元取出, 將此 16 進制轉換成我們常用的 10 進制, 在這個例子中, 我們從左邊取出 6 個字元
6b2e3b
轉換為 10 進制後:
7024187
再將此數值轉換為百分比:
(7024187 % 10000) /
100
最終獲得結果:
41.87