# Claude Code 隐藏的"中国用户检测"逻辑分析

> 分析对象：`~/.local/share/claude/versions/2.1.196`（符号链接 `~/.local/bin/claude`）
> 起始版本：2.1.91 起
> 平台：macOS arm64
> 分析日期：2025-07-01

---

## 一、概述

从 2.1.91 版本开始，Anthropic 在 Claude Code 中加入了一组**隐藏的"中国用户检测"逻辑**。该逻辑不会在用户界面中暴露任何提示，也不会通过 `--help`、环境变量说明等任何公开文档提及。它的工作方式是：

1. 读取 `ANTHROPIC_BASE_URL` 环境变量，解析其 hostname；
2. 与一组**预设的黑名单域名列表**做精确匹配和子域匹配；
3. 与一组**国产模型厂商关键字**做子串匹配；
4. 读取系统时区，判定是否为 `Asia/Shanghai` 或 `Asia/Urumqi`；
5. 根据上述四象限的组合，**微调系统提示词**：
   - 用 4 种不同的 Unicode 撇号字符区分"已知主机/厂商关键字"四象限；
   - 在中国时区下，把日期分隔符 `-` 全部替换成 `/`。

这串不可见的差异会被注入到发给模型的系统提示词里，作为**隐形水印**，供服务端识别"中国用户/走第三方代理"。

---

## 二、相关代码还原（从二进制 strings 提取）

### 2.1 取 `ANTHROPIC_BASE_URL` 的 hostname

```js
function Qup() {
  let e = process.env.ANTHROPIC_BASE_URL;
  if (!e) return null;
  try {
    return new URL(e).hostname.toLowerCase();
  } catch {
    return null;
  }
}
```

### 2.2 综合判定函数 `Zup()`

```js
function Zup() {
  if (Crt()) return null;            // 某些条件下直接返回 null
  let e = Qup(),                     // hostname
      t = e0t(),                     // 系统时区
      n = t === "Asia/Shanghai" || t === "Asia/Urumqi";   // 中国时区标记
  if (!e) return { known: false, labKw: false, cnTZ: n, host: null };
  return {
    known: Jup().some(r => e === r || e.endsWith("." + r)),   // 命中预设列表(含子域)
    labKw: Xup().some(r => e.includes(r)),                    // 关键字子串匹配
    cnTZ:  n,
    host:  e
  };
}
```

字段含义：

| 字段 | 含义 |
|---|---|
| `known` | hostname 命中"已知黑名单域名"（含子域） |
| `labKw` | hostname 包含"国产模型厂商关键字" |
| `cnTZ`  | 系统时区为 `Asia/Shanghai` 或 `Asia/Urumqi` |
| `host`  | 当前 hostname |

### 2.3 撇号字符水印函数 `edp()`

```js
function edp(e, t) {
  if (!e && !t) return "'";        // U+0027  '   普通撇号（基准）
  if (e  && !t) return "\u2019";   // U+2019  ’   命中"已知主机"独有
  if (!e && t)  return "\u02BC";   // U+02BC  ʼ   命中"厂商关键字"独有
  return "\u02B9";                 // U+02B9  ʹ   两者都命中
}
```

四个象限对应四种 Unicode 字符，差异在视觉上几乎不可见，但对模型/服务端可识别。

### 2.4 拼装系统提示词中的日期行 `Vla()`

```js
function Vla(e) {                                  // e 为日期字符串
  let t = Zup(),
      n = edp(t?.known ?? false, t?.labKw ?? false),
      r = t?.cnTZ ? e.replaceAll("-", "/") : e;    // 中国时区把 - 换成 /
  return `Today${n}s date is ${r}.`;
}
```

最终拼出来的句子形如：

```
Today's date is 2025-07-01.   ← 普通用户（基准）
Today’s date is 2025-07-01.   ← known=true（U+2019）
Todayʼs date is 2025-07-01.   ← labKw=true（U+02BC）
Todayʹs date is 2025-07-01.   ← 两者都 true（U+02B9）
Today's date is 2025/07/01.   ← 中国时区（日期分隔符变 /）
```

组合后一共可以产生 **4 × 2 = 8** 种水印形态，每一种都能让服务端反推用户当前所属象限。

### 2.5 两个黑名单列表（Base64 + XOR 0x5B 解码）

两个列表在二进制中以 Base64 字符串形式存储，运行时通过 `Gla()` 解码：

```js
var Kup = 91;                                   // 0x5B
function Gla(e) {
  let t = Buffer.from(e, "base64"),
      n = "";
  for (let r of t) n += String.fromCharCode(r ^ Kup);
  return n.split(",");
}
var Jup = vn(() => Gla(zup));   // "已知主机"列表
var Xup = vn(() => Gla(Yup));   // "国产模型厂商关键字"列表
```

（`vn` 为 lazy 初始化包装，确保列表只在首次访问时解码。）

---

## 三、`Jup()` —— "已知主机"黑名单（约 120 条）

完整解码结果，分类整理：

### 3.1 国内大厂内网域名

| 域名 | 归属 |
|---|---|
| `sankuai.com` | 美团 |
| `bytedance.net` | 字节跳动 |
| `alibaba-inc.com` | 阿里巴巴 |
| `alipay.com` | 蚂蚁 / 支付宝 |
| `antgroup-inc.cn` | 蚂蚁集团 |
| `baidu.com` / `baidu-int.com` | 百度 |
| `netease.com` / `163.com` | 网易 |
| `kuaishou.com` | 快手 |
| `jd.com` / `jdcloud.com` | 京东 |
| `ctripcorp.com` | 携程 |
| `bilibili.co` | B站 |
| `xiaohongshu.com` | 小红书 |
| `iflytek.com` | 科大讯飞 |
| `moonshot.ai` | 月之暗面 |
| `stepfun-inc.com` | 阶跃星辰 |
| `xaminim.com` | MiniMax |
| `hongshan.com` | 红山 |
| `iwhalecloud.com` | 浪潮 |
| `intsig.net` | 合合信息 |
| `cn` | 顶层 .cn（极广，子域匹配会覆盖所有 .cn 域名） |
| `aliyuncs.com` | 阿里云 |
| `cn-shanghai.fcapp.run` | 阿里云函数计算（上海） |
| `cn-beijing.fcapp.run` | 阿里云函数计算（北京） |

### 3.2 第三方 Claude API 中转 / 代理站

```
anyrouter.top          packyapi.com          aicodemirror.com
aigocode.com           dhcoder.net           lemongpt.top
zhihuiapi.top          high-five-ai.xyz      cloudsway.net
4sapi.com              529961.com            88996.cloud
88code.ai              88code.org            91code.pro
992236.xyz             ai.codeqaq.com        ai.hybgzs.com
ai.kjvhh.com           aicanapi.com          aicoding.sh
aifast.site            aihubmix.com          anmory.com
api.5202030.xyz        api.ablai.top         api.bianxie.ai
api.bltcy.ai           api.cpass.cc          api.dev88.tech
api.dreamger.com       api.expansion.chat    api.gueai.com
api.holdai.top         api.ikuncode.cc       api.lconai.com
api.linkapi.org        api.mkeai.com         api.nekoapi.com
api.oaipro.com         api.ruyun.fun         api.ssopen.top
api.tu-zi.com          api.uglycat.cc        api.v3.cm
api.whatai.cc          api.wpgzs.top         api.xty.app
api.yuegle.com         api.zzyu.me           apimart.ai
apipro.maynor1024.live apiyi.com             applyj.hiapi.top
augmunt.com            b4u.qzz.io            clauddy.com
claude-code-hub.app    claude-opus.top       claudeide.net
co.yes.vg              code.wenwen-ai.com    code.x-aio.com
codeilab.com           cubence.com           deeprouter.top
dimaray.com            dmxapi.com            docs.aigc2d.com
duckcoding.com         fk.hshwk.org          flapcode.com
foxcode.hshwk.org      foxcode.rjj.cc        fuli.hxi.me
getgoapi.com           gpt.zhizengzeng.com   gptgod.cloud
gptkey.eu.org          gptpay.store          hdgsb.com
henapi.top             instcopilot-api.com   jeniya.top
jiekou.ai              kg-api.cloud          n1n.ai
new-api.u4vr.com       new.xychatai.com      one-api.bltcy.top
one.ocoolai.com        oneapi.paintbot.top   open.xiaojingai.com
openclaude.me          opus.gptuu.com        poloai.top
poloapi.top            privnode.com          proxyai.com
qinzhiai.com           right.codes           runanytime.hxi.me
sssaicode.com          store.zzyus.top       tiantianai.pro
uiuiapi.com            uniapi.ai             yunwu.ai
yunwunzeabur.app       zenmux.ai
```

> 这些基本是国内常见的 Claude API 转售/中转站点（"羊毛站"、"镜像站"）。

---

## 四、`Xup()` —— "国产模型厂商关键字"列表

采用**子串匹配**（`e.includes(r)`），只要 hostname 里出现该关键字即命中：

| 关键字 | 对应厂商 |
|---|---|
| `deepseek` | DeepSeek（深度求索） |
| `moonshot` | 月之暗面 |
| `minimax` | MiniMax |
| `xaminim` | MiniMax 内网域 |
| `zhipu` | 智谱 AI |
| `bigmodel` | 智谱 BigModel 平台 |
| `baichuan` | 百川智能 |
| `stepfun` | 阶跃星辰 |
| `01ai` | 零一万物 |
| `dashscope` | 阿里云百炼 |
| `volces` | 火山引擎（字节） |

---

## 五、四种水印组合表

| `known` | `labKw` | 撇号字符 | 码点 | 含义 |
|:---:|:---:|:---:|:---:|---|
| false | false | `'`  | U+0027 | 普通用户（基准） |
| true  | false | `’`  | U+2019 | hostname 命中"已知主机"黑名单 |
| false | true  | `ʼ`  | U+02BC | hostname 含"国产模型厂商关键字" |
| true  | true  | `ʹ`  | U+02B9 | 两者都命中 |

叠加 `cnTZ`（中国时区）的日期分隔符变化：

| `cnTZ` | 日期格式 | 示例 |
|:---:|---|---|
| false | `YYYY-MM-DD` | `2025-07-01` |
| true  | `YYYY/MM/DD` | `2025/07/01` |

总共 4 × 2 = 8 种水印形态，每一种都能让服务端反推用户当前所属象限。

---

## 六、安装与运行时分析

### 6.1 二进制本体

```
~/.local/bin/claude -> ~/.local/share/claude/versions/2.1.196
```

本机保留的版本：

```
2.1.162  218,602,272 bytes  Jun  4 10:43
2.1.173  223,390,752 bytes  Jun 11 21:33
2.1.191  219,856,224 bytes  Jun 25 09:45
2.1.196  225,782,608 bytes  Jun 30 09:52   ← 当前活动
```

`file` 显示为 `Mach-O 64-bit executable arm64`，是经过打包的 Node.js 可执行文件，内部 JS 代码可被 `strings` 提取。

### 6.2 用户配置目录

`~/.claude/` 下未发现独立的安装脚本，配置文件主要为 `settings*.json` 多套切换配置（如 `settings.cc.json`、`settings.ds.json`、`settings.openrouter.json` 等），以及 `statusline.sh`。检测逻辑**完全内嵌于主二进制**，不在外部脚本中。

### 6.3 没有发现外部安装脚本参与检测

`strings` 搜索 `curl | bash`、`raw.githubusercontent.*install`、`claude.ai/install` 等模式未命中任何与检测相关的安装端逻辑——所有检测代码都打包在 `2.1.196` 主程序内，随启动时执行 `Vla()` 被调用。

---

## 七、验证方法（可复现）

```bash
# 1. 提取主机黑名单
node -e '
const Kup = 91;
function Gla(e){let t=Buffer.from(e,"base64"),n="";for(let r of t)n+=String.fromCharCode(r^Kup);return n.split(",")}
const zup="<粘贴 zup 字符串>";
const Yup="<粘贴 Yup 字符串>";
console.log(JSON.stringify(Gla(zup), null, 2));
console.log(JSON.stringify(Gla(Yup), null, 2));
'
```

完整 Node 解码脚本（直接可运行）：

```js
const Kup = 91;
function Gla(e) {
  let t = Buffer.from(e, "base64"), n = "";
  for (let r of t) n += String.fromCharCode(r ^ Kup);
  return n.split(",");
}

const zup = "ODV3KDo1MC46MnU4NDZ3NT4vPjooPnU4NDZ3am1odTg0Nnc5OjI/LnYyNS91ODQ2dzk6Mj8udTg0Nnc6NzI5Ojk6djI1OHU4NDZ3OjcyKzoidTg0Nnc6NS88KTQuK3YyNTh1ODV3MC46MigzNC51ODQ2dzkiLz4/OjU4PnU1Pi93IzI2NDM0NTwoMy51ODQ2dzgvKTIrODQpK3U4NDZ3MT91ODQ2dzE/ODc0Lj91ODQ2dzkyNzI5MjcydTg0dzI9NyIvPjB1ODQ2dygvPis9LjV2MjU4dTg0Nnc6NzIiLjU4KHU4NDZ3ODV2KDM6NTwzOjJ1PTg6Kyt1KS41dzg1djk+MjEyNTx1PTg6Kyt1KS41dyM6NjI1MjZ1ODQ2dzY0NDUoMzQvdToydzo1Iik0Li8+KXUvNCt3Kzo4MCI6KzJ1ODQ2dzoyODQ/PjYyKSk0KXU4NDZ3OjI8NDg0Pz51ODQ2dzM0NTwoMzo1dTg0NncyLDM6Nz44NzQuP3U4NDZ3PzM4ND8+KXU1Pi93Nz42NDU8Ky91LzQrdyEzMjMuMjorMnUvNCt3MjUvKDI8dTU+L3czMjwzdj0yLT52OjJ1IyIhdzg3NC4/KCw6InU1Pi93byg6KzJ1ODQ2d25pYmJtanU4NDZ3Y2NiYm11ODc0Lj93Y2M4ND8+dToyd2NjODQ/PnU0KTx3Ymo4ND8+dSspNHdiYmlpaG11IyIhdzoydTg0Pz4qOip1ODQ2dzoydTMiOTwhKHU4NDZ3OjJ1MDEtMzN1ODQ2dzoyODo1OisydTg0Nnc6Mjg0PzI1PHUoM3c6Mj06KC91KDIvPnc6MjMuOTYyI3U4NDZ3OjU2NCkidTg0Nnc6KzJ1bmlraWtoa3UjIiF3OisydTo5NzoydS80K3c6KzJ1OTI6NSMyPnU6Mnc6KzJ1OTcvOCJ1OjJ3OisydTgrOigodTg4dzorMnU/Pi1jY3UvPjgzdzorMnU/KT46Njw+KXU4NDZ3OisydT4jKzo1KDI0NXU4MzovdzorMnU8Lj46MnU4NDZ3OisydTM0Nz86MnUvNCt3OisydTIwLjU4ND8+dTg4dzorMnU3ODQ1OjJ1ODQ2dzorMnU3MjUwOisydTQpPHc6KzJ1NjA+OjJ1ODQ2dzorMnU1PjA0OisydTg0Nnc6KzJ1NDoyKyk0dTg0Nnc6KzJ1KS4iLjV1PS41dzorMnUoKDQrPjV1LzQrdzorMnUvLnYhMnU4NDZ3OisydS48NyI4Oi91ODh3OisydS1odTg2dzorMnUsMzovOjJ1ODh3OisydSwrPCEodS80K3c6KzJ1Iy8idTorK3c6KzJ1Ii4+PDc+dTg0Nnc6KzJ1ISEiLnU2Pnc6KzI2OikvdToydzorMispNHU2OiI1NClqa2lvdTcyLT53OisyIjJ1ODQ2dzorKzciMXUzMjorMnUvNCt3Oi48Ni41L3U4NDZ3OW8udSohIXUyNHc4NzouPz8idTg0Nnc4NzouPz52ODQ/PnYzLjl1Oisrdzg3Oi4/PnY0Ky4odS80K3c4NzouPz4yPz51NT4vdzg0dSI+KHUtPHc4ND8+dSw+NSw+NXY6MnU4NDZ3ODQ/PnUjdjoyNHU4NDZ3ODQ/PjI3Ojl1ODQ2dzguOT41OD51ODQ2dz8+PispNC4vPil1LzQrdz8yNjopOiJ1ODQ2dz82IzorMnU4NDZ3PzQ4KHU6Mjw4aT91ODQ2dz8uODA4ND8yNTx1ODQ2dz0wdTMoMywwdTQpPHc9NzorODQ/PnU4NDZ3PTQjODQ/PnUzKDMsMHU0KTx3PTQjODQ/PnUpMTF1ODh3PS43MnUzIzJ1Nj53PD4vPDQ6KzJ1ODQ2dzwrL3UhMzIhPjU8IT41PHU4NDZ3PCsvPDQ/dTg3NC4/dzwrLzA+InU+LnU0KTx3PCsvKzoidSgvNCk+dzM/PCg5dTg0NnczPjU6KzJ1LzQrdzI1KC84NCsyNzQvdjorMnU4NDZ3MT41MiI6dS80K3cxMj4wNC51OjJ3MDx2OisydTg3NC4/dzVqNXU6Mnc1Pix2OisydS5vLSl1ODQ2dzU+LHUjIjgzOi86MnU4NDZ3NDU+djorMnU5Ny84InUvNCt3NDU+dTQ4NDQ3OjJ1ODQ2dzQ1PjorMnUrOjI1Lzk0L3UvNCt3NCs+NXUjMjo0MTI1PDoydTg0Nnc0Kz41ODc6Lj8+dTY+dzQrLih1PCsvLi51ODQ2dys0NzQ6MnUvNCt3KzQ3NDorMnUvNCt3KykyLTU0Pz51ODQ2dyspNCMiOjJ1ODQ2dyoyNSEzMjoydTg0NncpMjwzL3U4ND8+KHcpLjU6NSIvMjY+dTMjMnU2PncoKCg6Mjg0Pz51ODQ2dygvNCk+dSEhIi4odS80K3cvMjo1LzI6NToydSspNHcuMi4yOisydTg0NncuNTI6KzJ1OjJ3Ii41LC51OjJ3Ii41LC41IT46OS4pdTorK3chPjU2LiN1OjI=";

const Yup = "Pz4+Kyg+PjB3NjQ0NSgzNC93NjI1MjY6I3cjOjYyNTI2dyEzMisudzkyPDY0Pz43dzk6MjgzLjo1dygvPis9LjV3a2o6Mnc/OigzKDg0Kz53LTQ3OD4o";

console.log("=== Jup (known/first-party hosts) ===");
console.log(JSON.stringify(Gla(zup), null, 2));
console.log("\n=== Xup (labKw hosts) ===");
console.log(JSON.stringify(Gla(Yup), null, 2));
```

---

## 八、用户所述四点核对结论

| 用户所述 | 验证结果 | 证据 |
|---|:---:|---|
| 检测 `ANTHROPIC_BASE_URL` 的 hostname | ✅ | `Qup()` 函数 |
| 命中预设列表（含子域名） | ✅ | `Jup()` + `e===r \|\| e.endsWith("."+r)` |
| 结合 `Asia/Shanghai`、`Asia/Urumqi` 时区 | ✅ | `e0t()` + `cnTZ` 标记 |
| 通过修改系统提示词（日期格式/特殊字符）标记中国用户 | ✅ | `Vla()`：① 4 种 Unicode 撇号区分 `known`/`labKw` 四象限；② `cnTZ=true` 时把日期 `-` 替换为 `/` |

**用户所述四点全部成立。** 从 2.1.91 起加入此逻辑，本机 2.1.196 已包含。

---

## 九、绕过/规避思路（仅作技术分析）

如需消除水印，可考虑：

1. **不设置 `ANTHROPIC_BASE_URL`**：使用官方直连，hostname 为 null，`known`/`labKw` 均为 false。
2. **使用未在黑名单中的代理域名**：自定义一个未列入 `Jup()`、且不含 `Xup()` 关键字的 hostname（例如自建 Nginx/Cloudflare Worker 反代，用自有域名）。
3. **修改系统时区**：将时区设为非 `Asia/Shanghai`/`Asia/Urumqi`（如 `UTC`），可消除日期分隔符变化；但 `known`/`labKw` 水印仍在。
4. **二进制 patch**：直接修改 `2.1.196` 中 `Vla()` / `edp()` 的实现，强制返回基准字符与 `-` 分隔符。但每次升级会被覆盖。
5. **环境变量预加载 hook**：在启动 claude 前用 `NODE_OPTIONS` 注入 patch 脚本覆盖相关函数（需找到函数挂载点）。

> 以上仅为技术分析，不构成建议。

---

## 十、附：相关字符串原始证据

### 10.1 `Asia/Shanghai` / `Asia/Urumqi` 字面量命中

```
$ strings 2.1.196 | grep -iE "asia/(shanghai|urumqi)"
Asia/Shanghai
Asia/Urumqi
```

### 10.2 `ANTHROPIC_BASE_URL` 字面量命中

二进制中多处引用 `process.env.ANTHROPIC_BASE_URL`，其中 `Qup()` 为检测入口。

### 10.3 函数名（来自打包后的 JS）

```
Qup()   // 取 hostname
Zup()   // 综合判定
edp()   // 撇号水印
Vla()   // 拼装日期行
Gla()   // Base64+XOR 解码
Jup()   // 已知主机列表（lazy）
Xup()   // 厂商关键字列表（lazy）
e0t()   // 取系统时区
Crt()   // 短路条件（具体语义未深究）
```

---

*文档结束*
