# 机器码生成逻辑说明 ## 一、整体流程 ``` 客户端生成 raw_machine_info → 加密传输 → 后端规范化 + MD5 → machine_code 存库/校验 ``` 1. **客户端(Rust)** - **仅用磁盘序列号**生成原始串:`DISK=xxx`(即 `raw_machine_info`),**不含网卡/MAC**,避免 IP、网卡变化导致同机不同码。 - 登录/解绑等接口在加密请求体里带上 `raw_machine_info`。 2. **后端(Python)** - 从解密参数里取 `raw_machine_info`(或兼容 `machine_code` 作为 raw)。 - 调用 `raw_machine_info_to_machine_code(raw)`:先规范化再 MD5,得到 32 位十六进制 `machine_code`。 - 登录时:若用户未绑定则写入 `user.machine_code`;已绑定则校验一致才允许登录。 - 解绑时:校验请求的 machine_code 与 `user.machine_code` 一致才允许解绑。 3. **规范化与 MD5** - 规范化:解析 `DISK=...`(可选 `;MAC=...`),对段内分号分隔的项排序后重组。 - `machine_code = MD5(规范化后的字符串)`。 --- ## 二、为何不考虑网卡 - IP、网卡(含虚拟网卡、VPN、多网卡枚举顺序)经常变化,容易导致同一台机器多次得到不同 machine_code。 - 仅用**磁盘序列号**(系统盘/根卷),同机、同盘下结果稳定,换机或换盘才会变。 --- ## 三、客户端策略(同机稳定) | 平台 | 磁盘 | |----------|------| | **macOS** | 优先 `diskutil info /` 根卷序列号;失败再用 system_profiler 多盘取第一个 | | **Windows** | wmic 取所有盘序列号,排序后取**第一个** | | **Linux** | lsblk / sys 取序列号,排序后取**第一个** | 多盘时只取「第一个」磁盘,避免外接盘插拔导致变化。 --- ## 四、仍可能变化的情况 - 更换/重装系统盘后,会得到新 machine_code,需在原设备解绑或后台清空 `user.machine_code` 后再登录。 --- ## 五、相关代码位置 - 客户端生成:`client-tauri/src-tauri/src/machine.rs`(`generate_machine_code()`、`get_disk_serial()`)。 - 后端计算:`backend-client/app/utils/machine_code.py`(`normalize_raw_machine_info`、`raw_machine_info_to_machine_code`)。 - 路由里取 machine_code:`backend-client/app/api/v1/router.py` 中 `_raw_machine_info_to_machine_code(decrypted_params)`。