avatar-research.md
2.2 KB
Avatar Storage Research
研究日期: 2026-07-11 目标: 找到 username → 头像文件路径的完整映射规则
核心发现
头像文件路径与 username 的映射基于 MD5(username),不是 UUID 或数据库字段。
路径规则
{data_root}/avatar/{hash[0:2]}/{hash[2:4]}/user_hd_{full_hash}.png
示例:
| username | MD5 (前8位) | 路径 |
|----------|------------|------|
| wxid_51ap3m6p9xs722 | 28ef8e12... | avatar/28/ef/user_hd_28ef8e129c...png |
| filehelper | 9e20f478... | avatar/9e/20/user_hd_9e20f47889...png |
文件命名优先级
user_hd_{hash}.png— 高清头像(优先)user_{hash}.png— 普通头像(回退)- 也可尝试
{hash[0:2]}/{hash[2:4]}/{hash}/user_hd_{hash}.png(有些版本嵌套 hash 子目录)
验证结果
| Username | Hash (前8位) | 文件存在 | 大小 (估算) |
|---|---|---|---|
wxid_51ap3m6p9xs722 |
28ef8e12 |
✅ YES | ~3KB |
filehelper |
9e20f478 |
❌ NO | N/A |
其他尝试的方法
- hdheadimginfo 表: WeChat DB 中该表存在但 sqlite3 在 root shell 中不可用,未能直接查询。MD5 方法已验证足够。
- rcontact 扩展字段: rcontact 表无直接头像路径字段。头像通过文件系统 + MD5 映射。
- ImgFlag / WxFileIndex: 未发现头像相关的 filename→username 映射表。
实现方案
import hashlib
def _resolve_avatar_path(username: str) -> str | None:
"""username → MD5 → avatar hash directory path"""
h = hashlib.md5(username.encode()).hexdigest()
base = f"{data_root}/avatar/{h[:2]}/{h[2:4]}"
for fname in [f"user_hd_{h}.png", f"user_{h}.png"]:
path = f"{base}/{fname}"
if os.path.exists(path):
return path
return None
已知限制
- 无 small_ 缩略图: 实际测试未发现
small_前缀的缩略图。返回原图,前端用 CSS 缩放。 - 无 username→hash 缓存表: 每次请求都需计算 MD5 + 检查文件系统。可在后续版本增加 LRU 缓存。
- 文件系统权限: 头像文件在 WeChat 数据目录下,需要
su权限读取。当前实现:su -c cp到/tmp后send_file。