FAQ 常见问题
使用中常遇到的问题与排错指引。
先试这条
90% 的"结果不对"都源于把网页地址当成了图标地址。先试 iconhash identify <url>(自动发现图标),再看下面分类排错。
速查决策树
安装与构建
Q: Lite 和 Full 该选哪个? 高频
一句话结论
- 内网/离线环境 → 选 Full(
-tags embed_fingerprints,指纹内嵌)。 - 能联网且在意体积 → 选 Lite(约 5MB,首次查询时按需下载指纹库)。
- Docker 镜像 → 默认 Lite,镜像更小、拉取更快。
两种变体对比
| 维度 | Lite | Full |
|---|---|---|
| 二进制体积 | ~5MB | ~8MB(含指纹库) |
| 指纹库 | 运行时按需下载 | 编译期内嵌 |
| 离线可用 | 需先 fingerprints update | 完全离线可用 |
| 构建命令 | go build . | go build -tags embed_fingerprints . |
| 适用场景 | 联网服务器、CI、容器 | 内网、隔离环境、便携 U 盘 |
Q: 编译报错 build constraints? 高频
关键点
Full 构建必须显式加 -tags embed_fingerprints,否则 Go 会因为 build constraint 跳过内嵌指纹的文件,导致链接期找不到符号或运行时指纹库为空。
正确与错误的编译命令
# ❌ 错误做法:未加 tag,指纹不会内嵌
go build .
# ✅ 正确做法(Full):内嵌完整指纹库
go build -tags embed_fingerprints .
# ✅ 或用 Make 一键构建
make build-full
# ✅ Lite 构建不需要 tag
go build -o iconhash .make 目标速查:
| Make 目标 | 等价命令 | 产物 |
|---|---|---|
make build | go build . | Lite 二进制 |
make build-full | go build -tags embed_fingerprints . | Full 二进制 |
make build-all | 交叉编译多平台 | dist/ 目录 |
Q: go install 安装后命令找不到?
根因
go install 把二进制放到 $GOPATH/bin(默认 ~/go/bin),而该目录通常不在默认 PATH 中。装得了 ≠ 用得了。
修复步骤
# 1. 查看 GOPATH/bin 实际路径
go env GOPATH # 输出例如 /home/user/go
# 2. 临时加入 PATH(当前会话)
export PATH=$PATH:$(go env GOPATH)/bin
# 3. 验证
iconhash --version写入 shell 配置以永久生效:
# bash 用户
echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.bashrc
source ~/.bashrc
# zsh 用户
echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.zshrc
source ~/.zshrc哈希相关
Q: 我的哈希和搜索引擎对不上? 最高频
最常见原因——输入的 URL 不是图标直接地址,而是网页地址:
一句话结论
用 identify 而非 url。identify 会自动发现真正的图标(解析 HTML、跟随 link[rel=icon]、回退 /favicon.ico),而 url 只对图标直链有意义。
完整排错步骤
- 确认输入类型:你给的是网页地址还是图标直链?
https://example.com→ 网页,必须用identifyhttps://example.com/favicon.ico→ 图标直链,可用url
- 用 identify 重算:bash带
iconhash identify https://example.com-d可看到发现的图标路径:bashiconhash identify https://example.com -d # 输出含 discovered icon: https://example.com/favicon.ico - 核对搜索引擎口径:Fofa/Shodan 用 int32,若你输出的是 uint32 加
--uint32互换。 - 网站可能用 SVG/动态图标:部分站点根域名图标和子页不同,以搜索引擎抓取时的根域图标为准。
- 仍对不上:浏览器手动访问
https://<域名>/favicon.ico,用iconhash url单独算这个直链,再比对。
Q: int32 和 uint32 哪个对? 高频
两者是同一个哈希的不同表示,搜索引擎各有偏好:
一句话结论
默认输出 int32(与 Fofa/Shodan 一致)。需要 uint32 加 --uint32。两者本质是同一 32 位值的有符号/无符号解读,没有对错,只有口径。
换算关系与各引擎口径
| 搜索引擎 | 期望格式 | IconHash 参数 |
|---|---|---|
| Fofa | icon_hash="-1161367058" | 默认 int32 |
| Shodan | http.favicon.hash:-1161367058 | 默认 int32 |
| 部分第三方工具/脚本 | 3133600238 | --uint32 |
换算:uint32 = int32 + 2^32(当 int32 为负数时)。例如 -1161367058 + 4294967296 = 3133600238。
Q: 为什么先 Base64 再哈希?
原理:Base64 中转的真实作用
这并非"Base64 让哈希更准",而是早期 Python mmh3 库的一个实现约定——它要求输入是字节串,而当时爬虫拿到的是原始二进制(favicon 可能含非 ASCII 字节)。开发者顺手用 base64.encodebytes 把二进制编码成 ASCII 字节串再喂给 mmh3.hash,这个组合被 Shodan 最早采用并固化成事实标准。
关键点:哈希的对象不是原始图标字节,而是图标的 Base64 编码字节。任何想与 Shodan/Fofa 互通的实现都必须复现这一步,否则同图不同值。
数据流:从图标字节到最终哈希
对比"直接对原始字节哈希"的错误路径:
# ❌ 错误:直接对原始字节算 mmh3,与搜索引擎不符
mmh3.hash(raw_bytes)
# ✅ 正确:先 Base64 再 mmh3,与 Shodan/Fofa 一致
mmh3.hash(base64.encodebytes(raw_bytes))IconHash 在内部严格复现了"先 Base64 再 MurmurHash3"的链路,因此输出可与主流搜索引擎直接对齐。
指纹相关
Q: 查不到指纹? 高频
三步排查
- Lite 用户先补库:
iconhash fingerprints update拉取最新指纹库。 - Full 用户查版本:可能是旧版二进制,指纹库较旧 → 重新
make build-full或升级。 - 确实没收录:用
iconhash url <图标直链>拿到哈希后,自行写入自定义 JSON 或提 PR。
自检命令序列
# 1. 确认构建变体与指纹库状态
iconhash fingerprints list | head
# 2. Lite 用户更新指纹库
iconhash fingerprints update
# 3. 用已知图标验证指纹库可用性(应为 confluence 等已知服务)
iconhash url https://www.atlassian.com/favicon.ico
# 4. 仍无结果 → 该图标大概率未收录,走自定义指纹流程
iconhash url <你的图标直链> # 拿到哈希Q: 如何添加自定义指纹?
两条路径
- 本地私有指纹:写自定义 JSON,通过 SDK
NewDBFromJSON或--fingerprints参数加载,不进主库、不影响他人。 - 公开通用指纹:提 PR 到
data/fingerprints.json,合入后随版本分发,惠及所有用户。
自定义 JSON 格式与加载方式
[
{
"hash": -1234567890,
"service": "my-app",
"category": "custom",
"tags": ["internal"],
"description": "我的内部应用"
}
]字段说明:
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
hash | int32 | 是 | MurmurHash3 哈希值(int32 口径) |
service | string | 是 | 服务/产品名 |
category | string | 否 | 分类,如 cms/router/custom |
tags | []string | 否 | 标签,便于检索过滤 |
description | string | 否 | 补充说明 |
CLI 加载:
iconhash identify <url> --fingerprints ./my-fp.jsonSDK 加载:
db, _ := fingerprint.NewDBFromJSON("./my-fp.json")
// 与内置库合并查询提 PR 时请同时补充 service 的可溯源链接(官网、GitHub 仓库),便于维护者核验。
API / MCP 服务
Q: API 返回 401? 高频
三种带 token 的方式(任选其一)
- Header:
Authorization: Bearer <token> - Query 参数:
?token=<token> - 启动时不设
--auth-token→ 公开模式,无需 token(仅适合内网)。
正确请求示例与常见坑
# ✅ Header 方式
curl -H "Authorization: Bearer your-token" \
"http://localhost:8000/hash/url?url=..."
# ✅ Query 参数方式
curl "http://localhost:8000/hash/url?url=...&token=your-token"
# ❌ 常见错误:Bearer 后多了一个空格,或 token 含换行
curl -H "Authorization: Bearer your-token " # 末尾空格 → 401排查清单:
- 启动命令是否带了
--auth-token your-token? - 客户端的 token 与服务端是否完全一致(含大小写、无前后空格)?
- 是否走的是 HTTPS/反代,被中间层剥掉了
Authorization头? - 若服务端根本没设
--auth-token却返回 401 → 属于 bug,请提 issue。
Q: Claude Code 连不上 MCP? 高频
排查顺序
按图自上而下:PATH → 配置 → 手动 stdio 测试 → 重启客户端。绝大多数失败卡在前两步。
配置文件位置与正确写法
配置应为:
{
"mcpServers": {
"iconhash": {
"command": "iconhash",
"args": ["mcp"]
}
}
}不同客户端的配置文件路径:
| 客户端 | 配置路径 |
|---|---|
| Claude Code(项目级) | .claude/settings.json |
| Claude Code(用户级) | ~/.claude/settings.json |
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json(macOS) |
手动测试 stdio(应能收到 JSON-RPC 握手响应):
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | iconhash mcp若卡住无输出,加 -d 看日志:
iconhash mcp -d最后别忘了重启 Claude Code——MCP 客户端只在启动时加载配置,热改不生效。
Q: API 端口被占用?
一句话解决
iconhash server 默认监听 :8000,被占用时直接换端口启动即可。
换端口与排查
# 1. 换端口启动
iconhash server -p 9000
# 2. 或用环境变量
ICONHASH_PORT=9000 iconhash server
# 3. 查看谁占用了 8000(Linux/macOS)
lsof -i :8000
# 或
ss -ltnp | grep :8000若端口被自己之前的 iconhash 进程占用(常见于重复启动):
# 找到并结束旧进程
pkill -f "iconhash server"生产环境建议用 systemd/容器托管,由进程管理器分配固定端口,避免手动冲突。
性能与批量
Q: 批量处理太慢? 高频
调优三档
- 起步:
-w 10(默认 5 偏保守,现代网络可翻倍)。 - 进阶:
-w 20,配合--timeout适当放宽(默认 10s,慢网可设 15s)。 - 大规模:上千 URL 时配合代理池分摊请求源 IP,避免被目标限流。
推荐配置与瓶颈定位
# 推荐配置:20 worker + JSON 输出
iconhash batch -f urls.txt -w 20 -o json > results.json
# 含超时与重试
iconhash batch -f urls.txt -w 20 --timeout 15 -o json > results.json瓶颈定位:
| 现象 | 可能瓶颈 | 处置 |
|---|---|---|
| worker 已 20 仍慢 | 网络带宽/目标限流 | 接入代理池,分摊源 IP |
| 单条耗时长 | DNS 解析慢 | 用本地 DNS 缓存或公共 DNS |
| 偶发超时多 | 目标站点慢/不可达 | 调高 --timeout,加 --retry |
| CPU 闲置却慢 | 等待 IO | 继续加 -w,上限受目标承受力制约 |
Q: 大批量时内存高?
根因
-o json 模式会把所有结果在内存里聚合成一个 JSON 数组再输出,10 万条 URL 会撑爆内存。-o csv / -o text 则是逐条流式输出,内存恒定在常数级。
流式输出与分批处理
# ✅ 大批量首选:csv 流式输出,内存恒定
iconhash batch -f urls.txt -w 20 -o csv > results.csv
# ✅ text 模式同样流式
iconhash batch -f urls.txt -w 20 -o text > results.txt
# 若必须用 json:拆分大文件,分批产出再合并
split -l 10000 urls.txt chunk_
for f in chunk_*; do
iconhash batch -f "$f" -w 20 -o json > "${f}.json"
done
# 合并(jq 把多个数组拼成一个)
jq -s 'add' chunk_*.json > results.json
rm -f chunk_*判定方法:批量任务跑起来后用 top/htop 观察 iconhash 进程 RSS,若随 URL 数线性增长 → 命中此问题,切 csv 即可。
其他
Q: 支持 IPv6 / Tor 吗?
支持情况
- IPv6:原生支持,无需额外配置,只要目标域名有 AAAA 记录且本机 IPv6 可达即可。
- Tor:通过
--proxy socks5://走 SOCKS5 代理,可访问.onion隐藏服务。
Tor / 代理用法
# 经 Tor 代理访问 onion 站点
iconhash identify https://example.onion \
--proxy socks5://127.0.0.1:9050
# HTTP 代理(IPv4/v6 均可)
iconhash identify https://example.com \
--proxy http://127.0.0.1:8080
# 带认证的 SOCKS5
iconhash identify https://example.com \
--proxy socks5://user:pass@127.0.0.1:9050前置条件:
- Tor:本机运行
tor,默认 SOCKS5 监听127.0.0.1:9050。 - IPv6:本机有全局 IPv6 地址,且防火墙未阻断出站。
Q: 命令记不住?
只记一条就够
日常只需记住 iconhash identify <url>,它能覆盖 90% 场景(发现图标 + 算哈希 + 查指纹)。其余命令按需 --help 查阅。
常用命令速查
| 场景 | 命令 |
|---|---|
| 算单个网站图标哈希 | iconhash identify <url> |
| 算图标直链哈希 | iconhash url <图标直链> |
| 批量 | iconhash batch -f urls.txt -w 20 -o csv |
| 起 API 服务 | iconhash server -p 8000 |
| MCP 模式 | iconhash mcp |
| 更新指纹库(Lite) | iconhash fingerprints update |
| 查看版本 | iconhash --version |
每个子命令都有详细帮助:iconhash identify --help、iconhash batch --help 等,帮助文本内含可复制的示例。
日常只需记住
iconhash identify <url>,其余命令--help查阅即可。
Q: 如何贡献?
贡献入口
- 代码:提 PR,建议先开 Issue 讨论方向。
- 指纹:向
data/fingerprints.json加条目,附可溯源链接。 - 文档:改
website/vitepress/docs/下的 Markdown。 - 问题反馈:直接提 Issue,附
iconhash --version与复现步骤。
提 PR 前的 checklist
- [ ] 本地
make test通过(含go vet、单元测试)。 - [ ] 新增指纹有可溯源的官网或仓库链接。
- [ ] 代码已
gofmt格式化(make fmt)。 - [ ] commit message 遵循约定式提交(
feat:/fix:/docs:)。 - [ ] 若改了 CLI 行为,同步更新文档与
--help示例。
仍未解决?
提 Issue 前必读
按上述决策树与各 Q 的排错步骤逐项排查后仍未解决,再提 Issue。Issue 必须包含以下四项,缺一不回复:
- 版本:
iconhash --version的完整输出(含构建变体 Lite/Full、Commit)。 - 完整命令:你实际敲的命令行(敏感 URL 可脱敏,但路径结构别改)。
- 期望 vs 实际:期望得到什么、实际得到什么(贴出哈希值)。
- 调试输出:加
-d重新跑一次,贴调试日志(含发现图标的最终 URL)。
缺少以上任一项的 Issue 将被直接关闭——这不是刁难,而是因为这些信息是定位问题的最低门槛,反复追问会拖慢所有人的节奏。
返回 文档首页。