签到天数: 7 天 [LV.3]偶尔看看II

大兔子
- UID
- 55708
- 僵尸币
- 6941
- 贡献度
- 0
- 注册时间
- 2018-7-12
- 在线时间
- 279 小时
- 最后登录
- 2026-8-15
 

|
不注册个乐园论坛账号能玩??
您需要 登录 才可以下载或查看,没有账号?注册

×
# 你哥杯抽签工具 · 公正性说明
**冻结版本:** NiGeCupTeamDraw / NiGeCupLocal **1.0**
**抽签页最后写入:** 2026-08-06 12:22:43
**本说明核对时间:** 2026-08-15
**抽签页指纹(SHA-256):**
```
982756210F06F63F8BA42963E2AB414AD1CE357D042A41082D7E5A2B022010DD
```
根据作者提供的文档,draw.html的SHA-256已对上。index.html保存差了一秒,主要是少了「退出登录」。
抽签逻辑在 `index.html`,本地服务 `server.py` 只负责名单和数据,**不参与选队、不参与抽签位**。
---
## 结论
1. **随机:** 源码没有针对玩家名、QQ、Steam64、楼层或某支战队字母的内定分支。随机数来自浏览器密码学接口 `crypto.getRandomValues`。淘汰赛签位是均匀随机排列。分队抽签是密码学随机,并遵守「预组小队必须整组入座、每队最多 6 人」;抽取顺序等于名单顺序,因此「谁跟谁一队」会受名单排序影响,但**不会偏向某一个字母队**。
---
## 一、如何证明不是另一份被改过的代码
### 关键文件痕迹
| 文件 | 作用 | 最后写入时间 | 大小(字节) | SHA-256 |
|---|---|---|---:|---|
| `index.html` | 分队抽签 + 淘汰赛抽签(全部算法) | 2026-08-06 12:22:43 | 68880 | `982756210F06F63F8BA42963E2AB414AD1CE357D042A41082D7E5A2B022010DD` |
| `server.py` | 本地名单 / Leetify 数据,不抽签 | 2026-08-04 10:45:27 | 16943 | `759818B31DA319744BBB803C2EC72C2A84C60DAA47E4A2DB7922D269AED0C964` |
| `start.bat` | 启动本地服务 | 2026-08-04 10:39:56 | 119 | `0787855CD66B35DDB8EBB9CD733B0945E04E40A19F81AAF3C89FCF416E0C543A` |
| `site/public/draw.html` | 托管版页面(与本地稿同一秒保存,仅多「退出登录」) | 2026-08-06 12:22:43 | 69496 | `41ED7819D3360243EA2F1C52823F98101C88477CBB3946E2C45EDDC4313DD1D6` |
### 抽签页改动时间线
目录 `site/work/sites-package-stage*` 里留有开发过程中的 `draw.html` 草稿,变化如下:
| 时间 | 草稿 | 说明 |
|---|---|---|
| 2026-08-04 10:45 | 约 58 KB | 首版;随机源为 `Math.random()` |
| 2026-08-04 11:36–11:55 | 约 59 KB | 托管/登录相关迭代 |
| 2026-08-06 08:42 | 约 71 KB | 改为 `crypto.getRandomValues`,并加入淘汰赛抽签 |
| 2026-08-06 12:22 | 本地 68880 / 托管 69496 | **冻结点**;两份同一秒写入,差别只有退出登录 |
8 月 6 日的改动是换更强的随机源、补淘汰赛功能,源码中**没有**按某个玩家或某支队伍写死的分支。
`server.py` 自 8 月 4 日 10:45 后再未改;它本来就不抽签。
---
## 二、如何证明是随机、没有内定
### 1. 随机从哪里来
抽签只在浏览器里执行。唯一随机入口:
```javascript
const randomUnit = () =>
crypto.getRandomValues
? crypto.getRandomValues(new Uint32Array(1))[0] / 4294967296
: Math.random();
```
- 有 `crypto.getRandomValues` 时(所有现代浏览器都有):使用操作系统提供的**密码学安全随机数**,不是普通的 `Math.random()`。
- 抽签结果、动画高亮、淘汰赛签位,都走这一个函数。
- `server.py`、Leetify 数据、胜率/Aim 排名**不参与**抽签。
现场可投影 `index.html` 中以下函数:`randomUnit`、`makePlan`、`doDraw`、`doKnockoutDraw`。
### 2. 没有作弊面
审查范围覆盖 `index.html` 全部脚本与 `server.py`。未发现:
- 按玩家 ID、QQ、Steam64、报名楼层加权或指定队伍;
- 「种子队 / 避开某队 / 内定签位」;
- 两套账(动画一套、结果另一套)。动画只是在可入座的战队上闪烁,最终入座来自同一次 `randomUnit()` 抽中的方案。
### 3. 分队抽签怎么随机
规则:96 人分成 A–P 共 16 队,每队 6 人;Excel 里「组队情况」相同的玩家必须抽进同一队。
算法(`makePlan`):
1. 按名单出现顺序,把「一个单排」或「一整支预组小队」当成一张签;
2. 列出当前还坐得下这张签的战队;
3. 在这些战队里**均匀随机**选一个;
4. 若某种随机走法会导致后面分不完,整盘重抽(最多 3000 次),保证能分完,同时每一步仍然随机。
这与世界杯抽签同类:每一步在合法选项里均匀抽,不是「先穷举所有分法再等概率挑一种」。
**模拟(8000 次,96 个单排):** 名单第 1 / 第 49 / 第 96 人进入 A–P 各队的次数都在期望值 500 附近波动,看不到某个字母被优待。
**需要公开说明的顺序效应(不是内定):**
- 抽取顺序 = 导入名单的顺序,代码没有先洗牌。
- 相邻两个单排抽进同一队的比例约 6.75%;名单首尾两人约 2.72%。完全均匀随机划分时期望约为 5.26%(5/95)。
- 若一支五排排在名单最前,紧跟其后的单排补上那个空位的机会接近 1/16,越靠后越低。
因此:没有内定行为。
源码逐步说明见同目录《名单顺序与同队概率说明.md》或用浏览器打开 `名单顺序与同队概率说明.html`(可 Ctrl+P 另存为 PDF)。
### 4. 淘汰赛抽签怎么随机
A–P 十六队按字母顺序上场:当前队在**尚未占用的签位**里均匀随机抽一个。这与把 16 个签位做一次均匀随机排列,每一种对阵排列概率相同。
**模拟(8000 次):** A 队落入 1–16 号签的次数约 467–530,贴近期望 500。
### 5. 流程上仍由编写者控制的部分
下列不是随机函数的问题,但是现场规则,建议当场宣布:
- 界面有「撤回一步」「重新抽签」。若使用,等于作废已抽结果。建议抽签开始后不再撤回,或事先约定何种情况才允许重置。
- 代码在浏览器运行,理论上可用开发者工具临时改脚本。建议投影整屏、抽签时不打开 F12,并用本文哈希核对磁盘文件。
---
|
|