Skip to content

FAQ 常见问题

使用中常遇到的问题与排错指引。

先试这条

90% 的"结果不对"都源于把网页地址当成了图标地址。先试 iconhash identify <url>(自动发现图标),再看下面分类排错。

速查决策树


安装与构建

Q: Lite 和 Full 该选哪个? 高频

一句话结论

  • 内网/离线环境 → 选 Full(-tags embed_fingerprints,指纹内嵌)。
  • 能联网且在意体积 → 选 Lite(约 5MB,首次查询时按需下载指纹库)。
  • Docker 镜像 → 默认 Lite,镜像更小、拉取更快。
两种变体对比
维度LiteFull
二进制体积~5MB~8MB(含指纹库)
指纹库运行时按需下载编译期内嵌
离线可用需先 fingerprints update完全离线可用
构建命令go build .go build -tags embed_fingerprints .
适用场景联网服务器、CI、容器内网、隔离环境、便携 U 盘

Q: 编译报错 build constraints高频

关键点

Full 构建必须显式加 -tags embed_fingerprints,否则 Go 会因为 build constraint 跳过内嵌指纹的文件,导致链接期找不到符号或运行时指纹库为空。

正确与错误的编译命令
bash
# ❌ 错误做法:未加 tag,指纹不会内嵌
go build .

# ✅ 正确做法(Full):内嵌完整指纹库
go build -tags embed_fingerprints .

# ✅ 或用 Make 一键构建
make build-full

# ✅ Lite 构建不需要 tag
go build -o iconhash .

make 目标速查:

Make 目标等价命令产物
make buildgo build .Lite 二进制
make build-fullgo build -tags embed_fingerprints .Full 二进制
make build-all交叉编译多平台dist/ 目录

Q: go install 安装后命令找不到?

根因

go install 把二进制放到 $GOPATH/bin(默认 ~/go/bin),而该目录通常不在默认 PATH 中。装得了 ≠ 用得了。

修复步骤
bash
# 1. 查看 GOPATH/bin 实际路径
go env GOPATH           # 输出例如 /home/user/go
# 2. 临时加入 PATH(当前会话)
export PATH=$PATH:$(go env GOPATH)/bin
# 3. 验证
iconhash --version

写入 shell 配置以永久生效:

bash
# 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 而非 urlidentify 会自动发现真正的图标(解析 HTML、跟随 link[rel=icon]、回退 /favicon.ico),而 url 只对图标直链有意义。

完整排错步骤
  1. 确认输入类型:你给的是网页地址还是图标直链?
    • https://example.com → 网页,必须用 identify
    • https://example.com/favicon.ico → 图标直链,可用 url
  2. 用 identify 重算
    bash
    iconhash identify https://example.com
    -d 可看到发现的图标路径:
    bash
    iconhash identify https://example.com -d
    # 输出含 discovered icon: https://example.com/favicon.ico
  3. 核对搜索引擎口径:Fofa/Shodan 用 int32,若你输出的是 uint32 加 --uint32 互换。
  4. 网站可能用 SVG/动态图标:部分站点根域名图标和子页不同,以搜索引擎抓取时的根域图标为准。
  5. 仍对不上:浏览器手动访问 https://<域名>/favicon.ico,用 iconhash url 单独算这个直链,再比对。

Q: int32 和 uint32 哪个对? 高频

两者是同一个哈希的不同表示,搜索引擎各有偏好:

一句话结论

默认输出 int32(与 Fofa/Shodan 一致)。需要 uint32 加 --uint32。两者本质是同一 32 位值的有符号/无符号解读,没有对错,只有口径

换算关系与各引擎口径
搜索引擎期望格式IconHash 参数
Fofaicon_hash="-1161367058"默认 int32
Shodanhttp.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 互通的实现都必须复现这一步,否则同图不同值。

数据流:从图标字节到最终哈希

对比"直接对原始字节哈希"的错误路径:

bash
# ❌ 错误:直接对原始字节算 mmh3,与搜索引擎不符
mmh3.hash(raw_bytes)

# ✅ 正确:先 Base64 再 mmh3,与 Shodan/Fofa 一致
mmh3.hash(base64.encodebytes(raw_bytes))

IconHash 在内部严格复现了"先 Base64 再 MurmurHash3"的链路,因此输出可与主流搜索引擎直接对齐。


指纹相关

Q: 查不到指纹? 高频

三步排查

  1. Lite 用户先补库iconhash fingerprints update 拉取最新指纹库。
  2. Full 用户查版本:可能是旧版二进制,指纹库较旧 → 重新 make build-full 或升级。
  3. 确实没收录:用 iconhash url <图标直链> 拿到哈希后,自行写入自定义 JSON 或提 PR。
自检命令序列
bash
# 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 格式与加载方式
json
[
  {
    "hash": -1234567890,
    "service": "my-app",
    "category": "custom",
    "tags": ["internal"],
    "description": "我的内部应用"
  }
]

字段说明:

字段类型必填说明
hashint32MurmurHash3 哈希值(int32 口径)
servicestring服务/产品名
categorystring分类,如 cms/router/custom
tags[]string标签,便于检索过滤
descriptionstring补充说明

CLI 加载:

bash
iconhash identify <url> --fingerprints ./my-fp.json

SDK 加载:

go
db, _ := fingerprint.NewDBFromJSON("./my-fp.json")
// 与内置库合并查询

提 PR 时请同时补充 service 的可溯源链接(官网、GitHub 仓库),便于维护者核验。


API / MCP 服务

Q: API 返回 401? 高频

三种带 token 的方式(任选其一)

  1. HeaderAuthorization: Bearer <token>
  2. Query 参数?token=<token>
  3. 启动时不设 --auth-token → 公开模式,无需 token(仅适合内网)。
正确请求示例与常见坑
bash
# ✅ 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 测试 → 重启客户端。绝大多数失败卡在前两步。

配置文件位置与正确写法

配置应为:

json
{
  "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 握手响应):

bash
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | iconhash mcp

若卡住无输出,加 -d 看日志:

bash
iconhash mcp -d

最后别忘了重启 Claude Code——MCP 客户端只在启动时加载配置,热改不生效。

Q: API 端口被占用?

一句话解决

iconhash server 默认监听 :8000,被占用时直接换端口启动即可。

换端口与排查
bash
# 1. 换端口启动
iconhash server -p 9000

# 2. 或用环境变量
ICONHASH_PORT=9000 iconhash server

# 3. 查看谁占用了 8000(Linux/macOS)
lsof -i :8000
# 或
ss -ltnp | grep :8000

若端口被自己之前的 iconhash 进程占用(常见于重复启动):

bash
# 找到并结束旧进程
pkill -f "iconhash server"

生产环境建议用 systemd/容器托管,由进程管理器分配固定端口,避免手动冲突。


性能与批量

Q: 批量处理太慢? 高频

调优三档

  • 起步-w 10(默认 5 偏保守,现代网络可翻倍)。
  • 进阶-w 20,配合 --timeout 适当放宽(默认 10s,慢网可设 15s)。
  • 大规模:上千 URL 时配合代理池分摊请求源 IP,避免被目标限流。
推荐配置与瓶颈定位
bash
# 推荐配置: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 则是逐条流式输出,内存恒定在常数级。

流式输出与分批处理
bash
# ✅ 大批量首选: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 / 代理用法
bash
# 经 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 --helpiconhash 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 必须包含以下四项,缺一不回复

  1. 版本iconhash --version 的完整输出(含构建变体 Lite/Full、Commit)。
  2. 完整命令:你实际敲的命令行(敏感 URL 可脱敏,但路径结构别改)。
  3. 期望 vs 实际:期望得到什么、实际得到什么(贴出哈希值)。
  4. 调试输出:加 -d 重新跑一次,贴调试日志(含发现图标的最终 URL)。

缺少以上任一项的 Issue 将被直接关闭——这不是刁难,而是因为这些信息是定位问题的最低门槛,反复追问会拖慢所有人的节奏。

👉 提交 Issue


返回 文档首页

基于 MIT 许可证发布