Re: [閒聊] 玩遊戲用BUG到底該不該被砍帳號?已回收
※ 引述《OrO3 (OrO3)》之銘言:
: 雖然現在的可以把亂數做到很像是真實的亂數
: 但函式庫的底層其實是依照公式以及表格,去計算出下一個數字的
: 在早期的賭場的吃角子老虎
: 用的就是很脆弱的亂數
: 那時候有兩個數學家到賭場去
: 盯著吃角子老虎很久,算出機器出的亂數的規律
: 然後數學家看準時機下了注,贏了大筆獎金
: 我忘記這個故事的後續如何
: 印象中是那兩個數學家,被賭場當成是作弊,趕出去了
: 獎金當然也被沒收了
: 不知道大家會怎麼想這件事
: 這算是利用bug作弊嗎?
: 說起來,像FGO的轉蛋遊戲,也是機率遊戲
: 如果有辦法透過大量收集數據
: 反推出,幾點幾分幾秒會出SSR
: 導致100次單抽,抽出五十幾隻五星
: 你會覺得這算是作弊嗎?
: PS. 以FGO的程式品質,我是真的覺得有可能反推的出來
其實很多人誤以為亂數為了不被發現規律就是得要把函數寫的非常複雜
或是參數給得非常多
卻往往忽略了記憶體(空間)成本以及速度(時間)成本
其實只要簡單的函式就能夠產生夠亂的值
而其實有些玩家宣稱能在亂數函式中找出規律值往往只是一時間的湊巧
許多像這種拿時間函數,或是拿你的身分證字號,抑或是拿隔壁老王的出生年月日
...等等當參數去對應UR,SSR,特定的強角,SSR安部奈奈,甚至是垃圾
這種x對應於y的方式 我們統稱叫hash
換數學式子上,就是在非無限大的集合X與Y使得
f(x) = y (對於所有 x 屬於 X, y 屬於 Y)
根據鴿籠原理,若N(X) > N(Y) 一定會有兩個x1與x2以上使得 x1!=x2
f(x1) = f(x2)
這叫做碰撞
當然會有一些函式 (前提是 N(X) <= N(Y) ) 會讓碰撞機率最小
這叫做"perfect hash function"
其實wiki上有列出其中一個perfect hash function
f(x) =( kx mod p ) mod N(Y)
其中p是一個極大的質數, k 只是一個參數
但是最後不論你的f(x)怎麼設
還是免不了生日問題
也就是在1~d中任意取(f(x))n個整數(n<=d)使得某兩個整數以上一樣的機率為
1-(1-1/d)*(1-2/d)* ... *(1-n-1/d)
趨近於 1-e^(-n*(n-1)/(2*d))
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.236.35.20
※ 文章網址: https://www.ptt.cc/bbs/C_Chat/M.1508154435.A.E23.html
推
10/16 19:47,
8年前
, 1F
10/16 19:47, 1F
→
10/16 19:49,
8年前
, 2F
10/16 19:49, 2F
推
10/16 19:49,
8年前
, 3F
10/16 19:49, 3F
→
10/16 19:49,
8年前
, 4F
10/16 19:49, 4F
→
10/16 19:50,
8年前
, 5F
10/16 19:50, 5F
推
10/16 19:57,
8年前
, 6F
10/16 19:57, 6F
推
10/16 19:57,
8年前
, 7F
10/16 19:57, 7F
推
10/16 19:57,
8年前
, 8F
10/16 19:57, 8F
→
10/16 19:58,
8年前
, 9F
10/16 19:58, 9F
→
10/16 19:58,
8年前
, 10F
10/16 19:58, 10F
→
10/16 19:59,
8年前
, 11F
10/16 19:59, 11F
→
10/16 20:00,
8年前
, 12F
10/16 20:00, 12F
→
10/16 20:00,
8年前
, 13F
10/16 20:00, 13F
→
10/16 20:01,
8年前
, 14F
10/16 20:01, 14F
→
10/16 20:01,
8年前
, 15F
10/16 20:01, 15F
→
10/16 20:01,
8年前
, 16F
10/16 20:01, 16F
推
10/16 20:02,
8年前
, 17F
10/16 20:02, 17F
→
10/16 20:02,
8年前
, 18F
10/16 20:02, 18F
→
10/16 20:02,
8年前
, 19F
10/16 20:02, 19F
→
10/16 20:03,
8年前
, 20F
10/16 20:03, 20F
→
10/16 20:03,
8年前
, 21F
10/16 20:03, 21F
→
10/16 20:03,
8年前
, 22F
10/16 20:03, 22F
→
10/16 20:04,
8年前
, 23F
10/16 20:04, 23F
→
10/16 20:04,
8年前
, 24F
10/16 20:04, 24F
→
10/16 20:04,
8年前
, 25F
10/16 20:04, 25F
→
10/16 20:04,
8年前
, 26F
10/16 20:04, 26F
→
10/16 20:05,
8年前
, 27F
10/16 20:05, 27F
→
10/16 20:05,
8年前
, 28F
10/16 20:05, 28F
→
10/16 20:06,
8年前
, 29F
10/16 20:06, 29F
→
10/16 20:06,
8年前
, 30F
10/16 20:06, 30F
→
10/16 20:06,
8年前
, 31F
10/16 20:06, 31F
→
10/16 20:06,
8年前
, 32F
10/16 20:06, 32F
→
10/16 20:08,
8年前
, 33F
10/16 20:08, 33F
→
10/16 20:08,
8年前
, 34F
10/16 20:08, 34F
→
10/16 20:09,
8年前
, 35F
10/16 20:09, 35F
→
10/16 20:10,
8年前
, 36F
10/16 20:10, 36F
推
10/16 20:10,
8年前
, 37F
10/16 20:10, 37F
→
10/16 20:11,
8年前
, 38F
10/16 20:11, 38F
→
10/16 20:11,
8年前
, 39F
10/16 20:11, 39F
→
10/16 20:11,
8年前
, 40F
10/16 20:11, 40F
→
10/16 20:12,
8年前
, 41F
10/16 20:12, 41F
→
10/16 20:12,
8年前
, 42F
10/16 20:12, 42F
→
10/16 20:13,
8年前
, 43F
10/16 20:13, 43F
→
10/16 20:13,
8年前
, 44F
10/16 20:13, 44F
→
10/16 20:14,
8年前
, 45F
10/16 20:14, 45F
→
10/16 20:14,
8年前
, 46F
10/16 20:14, 46F
→
10/16 20:14,
8年前
, 47F
10/16 20:14, 47F
→
10/16 20:15,
8年前
, 48F
10/16 20:15, 48F
→
10/16 20:16,
8年前
, 49F
10/16 20:16, 49F
推
10/16 20:16,
8年前
, 50F
10/16 20:16, 50F
→
10/16 20:16,
8年前
, 51F
10/16 20:16, 51F
→
10/16 20:17,
8年前
, 52F
10/16 20:17, 52F
→
10/16 20:18,
8年前
, 53F
10/16 20:18, 53F
→
10/16 20:19,
8年前
, 54F
10/16 20:19, 54F
→
10/16 20:20,
8年前
, 55F
10/16 20:20, 55F
→
10/16 20:25,
8年前
, 56F
10/16 20:25, 56F
→
10/16 20:26,
8年前
, 57F
10/16 20:26, 57F
→
10/16 20:26,
8年前
, 58F
10/16 20:26, 58F
→
10/16 20:26,
8年前
, 59F
10/16 20:26, 59F
→
10/16 20:31,
8年前
, 60F
10/16 20:31, 60F
推
10/16 20:33,
8年前
, 61F
10/16 20:33, 61F
推
10/16 20:50,
8年前
, 62F
10/16 20:50, 62F
→
10/16 20:52,
8年前
, 63F
10/16 20:52, 63F
推
10/16 20:53,
8年前
, 64F
10/16 20:53, 64F
→
10/16 20:56,
8年前
, 65F
10/16 20:56, 65F
有人說用秒當亂數種子所產生的亂數很容易被察覺
那我們來看C的亂數
以下是用C的rand以秒當種子隨機5000次取0~4所得的機率,原始碼以及結果如下
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define TIMES 5000
int main(){
int result[5]={0};
int i;
unsigned seed;
seed = (unsigned)time(NULL);
srand(seed);
for(i=0; i<TIMES; ++i)
result[rand()%5]++;
printf("0: %f\n1: %f\n2: %f\n3: %f\n4: %f"
,(double)(result[0])/TIMES
,(double)(result[1])/TIMES
,(double)(result[2])/TIMES
,(double)(result[3])/TIMES
,(double)(result[4])/TIMES);
return 0;
}
0: 0.201800
1: 0.188200
2: 0.205600
3: 0.203400
4: 0.201000
你會發現誤差只在0.001~3附近,也就是5000次大夠只有1至2次偏向某個數字
然後觀察rand的原始碼,你會發現
for (i = 1; i < kc; ++i)
{
/* This does:
state[i] = (16807 * state[i - 1]) % 2147483647;
but avoids overflowing 31 bits. */
long int hi = word / 127773;
long int lo = word % 127773;
word = 16807 * lo - 2836 * hi;
if (word < 0)
word += 2147483647;
*++dst = word;
}
原始碼只是某些對於質數的四則運算
算是一個有意點複雜的perfect hash function
雖然對於某些種子會產生意料的規律性,但是對於產生隨機而言綽綽有餘
※ 編輯: jpopaholic (223.138.208.152), 10/16/2017 21:08:40
推
10/16 21:07,
8年前
, 66F
10/16 21:07, 66F
推
10/16 21:13,
8年前
, 67F
10/16 21:13, 67F
→
10/16 21:13,
8年前
, 68F
10/16 21:13, 68F
→
10/16 21:14,
8年前
, 69F
10/16 21:14, 69F
→
10/16 21:15,
8年前
, 70F
10/16 21:15, 70F
→
10/16 21:15,
8年前
, 71F
10/16 21:15, 71F
→
10/16 21:15,
8年前
, 72F
10/16 21:15, 72F
→
10/16 21:16,
8年前
, 73F
10/16 21:16, 73F
推
10/16 21:16,
8年前
, 74F
10/16 21:16, 74F
→
10/16 21:17,
8年前
, 75F
10/16 21:17, 75F
→
10/16 21:17,
8年前
, 76F
10/16 21:17, 76F
→
10/16 21:17,
8年前
, 77F
10/16 21:17, 77F
→
10/16 21:19,
8年前
, 78F
10/16 21:19, 78F
→
10/16 21:19,
8年前
, 79F
10/16 21:19, 79F
推
10/16 21:26,
8年前
, 80F
10/16 21:26, 80F

推
10/17 14:40,
8年前
, 81F
10/17 14:40, 81F
→
10/17 14:40,
8年前
, 82F
10/17 14:40, 82F
→
10/17 14:40,
8年前
, 83F
10/17 14:40, 83F
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 11 之 11 篇):