--- name: entropy-cipher description: "用私有字符表把文本编码成汉字密文,或把汉字密文还原成明文。当用户需要把链接、微信号、联系方式藏进普通中文里(避免被聊天平台或风控识别),或需要解开一段用《千字文》之类的字符表编码的汉字时使用。两种模式:字节级(密钥是一段字符表文本)与词级(密钥只有一个种子,密文读起来像中文)。提供 MCP 服务器(build_table / encrypt / decrypt)与开放 HTTP 接口。" --- # 熵加密 把任意文本按 UTF-8 字节逐个查表,替换成汉字。链接结构、域名、账号一起被替换,平台看到的是一段普通中文。 ## 什么时候用 - 需要在聊天里发链接、微信号、订单号,又不想被自动识别或拦截 - 收到一段"看着像中文但读不通"的汉字,需要还原 - 为自己的产品接入"可读的密文"能力 **发之前先自检**:`verify` 拿密文 + 会话串试解一次。注意词级模式下错的会话串**也会**解出一段像中文的文本,所以它给的是"解出了什么",不是"对了没" —— 读不读得通才是判断标准。 **要起一段新的约定**,先用 `generate_phrase`(或 `POST /api/phrase`)拿口令:它一次给全口令、实际种子、念读版、会话串与模式指纹。校验位是服务端算的,手抄错字会被当场拦下。 ## 什么时候不用 - 高风险通信:用 Signal、WireGuard 或 age,不要用这套 - 加密文件:这里只处理文本 - 对方需要直接阅读内容:这套方案的前提就是内容不可读 ## 两种模式 | 模式 | 密钥 | 密文观感 | 约定成本 | |---|---|---|---| | **字节级**(`mode=dedup/hash/raw`) | 一段字符表文本 | 逐字节换成汉字 | 传一段文本 + 核对指纹 | | **词级**(`mode=word`) | 一个**种子字符串** | 中文部分读起来像另一句话,非中文走符号层 | **只传一个种子** | 词级模式的三层替换(各层字符集互不相交,因此解密无歧义): 1. **词 → 词**:按内置词表(12043 词)切分,每个词换成**同长度、同词频档**的另一个词;功能词(的/了/是/在…)不变。 2. **单字 → 单字**:未命中词表的单个汉字换成常用字表(1500 字)里的另一个字,密文仍是汉字。 3. **非中文 → 符号**:链接、数字、字母逐字节换成符号表(256 个符号)里的符号(避免生僻汉字在 IM 里显示成豆腐块)。 词级模式下 `source` 不需要传,`fingerprint` 是**种子**的指纹,核对方式与字节级一致。 **自定义词表**(可选):传 `words`(一行一词),它排在内置词表前面,分词时优先命中 —— 行业黑话、代号、内部术语会被整体替换。**双方必须用同一份词表**,词级指纹把它算进去了,一方有一方没有时指纹立刻不同。 **可读口令**:种子可以写成 `词-词-数字-校验位`(例如 `芦苇-湖泊-9066-0MKN`),前三段是实际生效的种子,末四位是校验位。传 `seed_phrase` 即可,服务端会校验;抄错了直接报错,不会给"看着像对"的结果。 ## 核心规则(字节级,只需双方约定一张表) 1. **字符表**:一段双方各自持有的文本。建表规则三选一: - `dedup`:按出现顺序取前 N 个**不同**汉字;再把首字节区(0xE0–0xEF)的 k 个字各复制到另一段首字节槽位(0xC2–0xD1),于是同一密文字对应多个合法字节,解密存在多解。歧义时**取序号较大的那个槽位**。 - `hash`:同样取字,但顺序由整段文本的 FNV-1a 哈希派生——文本改一个字符,表与密文全变。 - `raw`:原样取前 N 个字,保留重复。 2. **编码**:非标点字符取 UTF-8 字节逐字节查表;`,` `.` `!` `?` `,` `。` `!` `?` 原样透传(中文标点因此只占 1 字而不是 3 字节)。 3. **掩码**(可选):字节先与一条由"表字符串哈希"播种的 PRNG 流异或。开启后重复模式被摧毁,外部无法验证任何候选明文。 4. **N ≠ 256 时**改为打包路径:每 log2(N) bit 一段,前置 2 字节大端长度用于去掉末组补零;此时标点不再透传,且表必须是单射。 **表即密钥。** 表泄露等于密文变明文,不要外传。 ## 调用方式 ### MCP(推荐) stdio:`python mcp/server.py` HTTP:`POST https://entropycipher.dev/api/mcp`,JSON-RPC 2.0 工具: | 工具 | 入参 | 出参 | |---|---|---| | `build_table` | source, seed, mode, n, amb | table(256 字)、fingerprint(8 位十六进制);词级只给 seed | | `encrypt` | text, source/seed, mode, n, amb, mask | cipher、fingerprint | | `decrypt` | cipher, source/seed, mode, n, amb, mask | plain、candidates、count | | `identify_table` | fingerprint 或 source | 这份字符集是哪个内置经典,还是自定义表 | | `generate_phrase` | 无 | | | 生成一段能念的口令:口令、种子、念读版、会话串、指纹 | | `identify_sender` | cipher + sessions[] | 逐个会话串试解;给出 confidence 与候选列表(带相似度) | | `check_session` | session(+words) | 会话串体检:校验位、词表指纹、最终种子与指纹 | | `self_check` | 无 | 跑一遍全链路自检,逐项返回结论与耗时 | **群发**:`encrypt` 接受 `recipients` 数组(每位收件人一份密文,可带自己的 `session` 或 `text`),一次最多 50 条,单条出错不影响整批。 **预检**:`encrypt` / `decrypt` 传 `dry_run: true` 只回校验结果,不回密文或明文。 **认领密文**:`decrypt` 接受 `sessions` 数组(逐个会话串试解),或用 MCP 工具 `identify_sender`。注意词级模式下错的会话串也能解出一段像中文的文本(词按同长度同词频档置换,用词频率几乎一样),这**不是**密码学判定 —— 接口因此不猜赢家:`confidence=single` 表示只有一条能解出(那条一定是你的),`multiple` 表示多条都能解出,`candidates` 会把候选与彼此差异都列出来,最终靠语义确认;字节级模式下解不出合法 UTF-8 才是硬信号。 **群发**:`encrypt` 接受 `recipients` 数组 —— 同一段明文,按各人自己的会话串各加密一份(群里每个人收到的都是只有他能解开的密文)。某一位出错只影响那一位。 **念读版**:口令可以念出来 —— `EC1:芦苇-湖泊-9066-0MKN::-` → `衣 希 一 · 芦 苇 湖 泊 · 九 零 六 六 · 零 艾姆 凯 嗯`。打电话对口令时用这个;`check_session` 的结果里带 `spell`。 **临时口令**:会话串支持 `EC2:口令:词表指纹:掩码:签发时间:有效期`(分钟),过期后解析直接被拒(不是"提示过期",是真的解不了),容忍 5 分钟时钟偏差。`encrypt` 传 `ttl_minutes` 即可生成。注意这是"过期即失效",不是"用一次即失效"。 **会话串**:词级模式可以传 `session`(`EC1:口令:词表指纹:掩码标记`),一次把口令、自定义词表、掩码开关都约定清楚;口令校验位或词表指纹对不上会直接报错。响应里会给出 `session` 与 `share_link`(扫码即可打开工具并填好整套约定)。 **dry_run**:加 `dry_run: true` 只校验不出内容 —— encrypt 只回指纹与表信息,decrypt 只回答"这段密文能不能解出来"。适合批量预检,密文与明文都不落日志。 **批量**:`encrypt` 与 `decrypt` 都可以传 `items` 数组(最多 50 条),返回 `{"results": [...], "count": n}`;单条出错时该条结果里带 `error`,不影响其余条目。 **工作流**:先 `build_table` 拿到表与指纹 → **双方核对指纹一致** → 再 `encrypt` 或 `decrypt`。指纹不一致说明字符集文本不同(版本、换行、标点差异),此时任何结果都不可信。 **除工具外还有**:MCP `resources/list` 提供 `entropy://tables/index`(内置表清单)与 `entropy://tables/`(十部经典全文,可直接当字符集);`prompts/list` 提供七个可直接执行的提示词:`encrypt_text` / `decrypt_text` / `share_link` / `group_chat` / `encrypted_call` / `start_agreement`(起一段新约定)/ `claim_cipher`(认领密文)。 **HTTP 接口**:`POST /api/encrypt`、`POST /api/decrypt`、`POST /api/identify`(按指纹或原文识别字符集来源)、`POST /api/event`(埋点)、`GET /api/stats`(聚合计数,只对同源或带 `STATS_TOKEN` 的运维请求开放)。 ### 上手包 `GET /api/agent-kit` 返回一条 JSON:两种模式的参数与差异、推荐工作流、端点清单、可直接复制的请求示例、以及注意事项(算法公开、建议加随机串、别把字符集写进日志)。别的 Agent 不读文档也能直接上手。 ### 场景提示词 `prompts/list` 给八个:`encrypt_text`、`decrypt_text`、`share_link`(藏链接)、`group_chat`(群聊里每人一份)、`encrypted_call`(加密通话)、`start_agreement`(起一段新约定:生成口令 → 核对指纹 → 加密)、`claim_cipher`(认领密文:试会话串、看 confidence、按语义确认)、`troubleshoot`(按症状排查:解不开、指纹对不上、认领分不清、会话串失效…)。 ### 选哪条路 | 场景 | 用什么 | |---|---| | 把链接藏进普通中文 | 字节级 + 双方各持字符表 | | 群聊里说一句只有某个人懂的话 | 词级(一个口令就够,可给每人不同措辞) | | 加密通话 | 字节级,可开掩码 | | 一次处理多条 | `items` 数组(最多 50 条,单条出错不影响整批) | ### 自检 `GET /api/self-check` 跑一遍全链路(建表 → 加密 → 解密 → 会话串 → 词级往返 → 认领 → 识别 → 文档契约 → 吞吐),逐项返回结论与耗时,`ok` 表示是否全部通过。环境换了先跑它。 ### HTTP 接口 - `POST /api/encrypt`、`POST /api/decrypt`、`POST /api/event` - 描述见 `/api/openapi.json` ### 本地页面 `/app.html`:全部在浏览器里跑,文本与字符表都不离开设备。 ## 随包文件(按需读,不必一次全读) | 文件 | 什么时候读 | |---|---| | `scripts/ec.py` | 要在命令行里加解密时。零依赖,给 `--api https://站点` 走接口,不给就用本地内核 | | `references/endpoints.md` | 要查某个 HTTP 端点的参数与示例时 | | `references/mcp.md` | 要查 MCP 的工具、资源、提示词时 | | `references/recipes.md` | 要照抄调用配方时(起约定、群发、认领、批量、预检、自检) | | `references/troubleshooting.md` | 遇到解不开、指纹对不上、认领分不清时 | `scripts/ec.py` 常用法: ```bash python scripts/ec.py encrypt --text "今晚八点老地方见" --seed "芦苇-湖泊-9066" python scripts/ec.py decrypt --cipher "..." --seed "芦苇-湖泊-9066" python scripts/ec.py index # 打印这个服务的地图(工具/提示词/资源/端点/场景) python scripts/ec.py verify --cipher "密文" --session "EC1:..." # 自检:这段配着这条会话串能不能解开 python scripts/ec.py session-check --session "EC1:芦苇-湖泊-9066-0MKN::-" python scripts/ec.py encrypt --text "甲方乙方今晚见" --seed "芦苇-湖泊-9066" --words "甲方乙方" python scripts/ec.py self-check ``` 自定义词表可以直接用 `--words "词1 词2"` 给(也可用 `--words-file 词表.txt`)。加上之后这些词会**整体替换**,而不是被拆成单字;词表指纹会进模式指纹,双方必须一致。 输出是 JSON。这个脚本不写盘、不留日志、不发第三方请求。 MCP 侧还能直接读资源:**`entropy://index` 是入口**(命令行里 `python scripts/ec.py index` 打印同一份)(这个服务能干什么:模式、工具、提示词、资源、端点、隐私承诺、从哪开始),然后:`entropy://endpoints`(端点目录)、`entropy://agent-kit`(上手包)、`entropy://recipes`(配方)、`entropy://events`(这个站会记哪些埋点事件、每个事件是什么意思)、`entropy://self-check`(把这个部署的全链路跑一遍,只读、不含用户数据)、`entropy://skill`(本文件全文)、`entropy://tables/index` 与 `entropy://tables/`(内置字符表)。 ## 给 AI 的建议 - 解密返回多个候选时,把候选都列出来并说明歧义来源(歧义槽),不要只报第一个 - 字符集是密钥。除非用户明确要求,不要把字符集写进公开日志、提交记录或对话摘要 - 明文里建议加一段随机串或暗语:攻击者猜不到真解时,加密才真正成立 - 需要"看起来像正常中文"时,选同语言风格的字符集;表里混多种文字会让密文风格不一致 - 想让约定成本最低(只传一个短字符串)就用词级模式:传 `mode="word"` 与 `seed` - 词级模式下的约定卡可直接贴给对方: ``` 模式 = 词级(表由种子派生,双方只约定种子) 种子 = "<双方约定的种子>" 还原:明文 = 拼接( 对 "密文" 切分后的每个 t : 若 t 在词表中 则 取映射前的词 否则 若 t 在单字表中 则 取原字 否则 取符号表对应的字节 ) ``` ## 校验 ```bash python mcp/server.py --selfcheck # 加解密往返自检 python tests/test_core.py # 内核与前后端一致性 ```