"""只读诊断:同一个会话的档案指纹在多次采样之间是否稳定。 档案键 = 头像感知哈希(8B) + 名称哈希(32B),而 store.has_record() 是精确匹配。 只要指纹漂移,同一个联系人就会被当成“首次遇到”,从而丢弃复制到的聊天文字、 只靠截图回复。这里量化漂移幅度。 """ import os import sys import time sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import numpy as np import wechat_bot as bot_module def hamming(a: bytes, b: bytes) -> int: return (int.from_bytes(a, "big") ^ int.from_bytes(b, "big")).bit_count() def main(): rounds = int(sys.argv[1]) if len(sys.argv) > 1 else 8 bot = bot_module.WeChatBot() bot.safe_window_mode = True bot.auto_activate_window = True if not bot.connect(activate=False, wait_if_missing=False): print("[-] 未挂载到企业微信窗口") return if not bot._ensure_visible(): print("[-] 企业微信未能切到前台") return print( "容差: 头像 %d 位以内算同一人;名称使用模糊匹配" % bot_module.WeChatBot._FP_HAMMING_TOL ) samples = [] for index in range(rounds): img = bot.capture_session_list() selected_y = bot.detect_selected_row(img) if selected_y < 0: print(" 第 %d 次采样:未检测到选中行" % (index + 1)) time.sleep(0.4) continue avatar = bot._raw_session_fingerprint(img, selected_y, row_center=True) name = bot._session_name_fingerprint(img, selected_y, row_center=True) full = bot._session_fingerprint(img, selected_y, row_center=True) samples.append((selected_y, avatar, name, full)) print( " 第 %d 次采样:选中行 y=%-4d 头像=%s 名称=%s 完整键=%s" % (index + 1, selected_y, avatar.hex(), name.hex()[:16] + "…", full.hex()[:16] + "…") ) time.sleep(0.4) if len(samples) < 2: print("样本不足,无法比较。") return print("\n[行中心] y 取值: %s" % sorted({s[0] for s in samples})) print("[头像哈希] 去重后 %d 种" % len({s[1] for s in samples})) print("[名称哈希] 去重后 %d 种" % len({s[2] for s in samples})) print("[完整档案键] 去重后 %d 种 <- 大于 1 就意味着同一会话会被反复当成新会话" % len({s[3] for s in samples})) base_y, base_avatar, base_name, _ = samples[0] worst = 0 for y, avatar, name, _full in samples[1:]: distance = hamming(base_avatar, avatar) worst = max(worst, distance) if distance: print( " 头像相对第 1 次漂移 %2d 位(y %d→%d)%s" % (distance, base_y, y, " 超出容差!" if distance > bot_module.WeChatBot._FP_HAMMING_TOL else "") ) print("[结论] 头像最大漂移 %d 位,容差 %d 位" % (worst, bot_module.WeChatBot._FP_HAMMING_TOL)) # 行中心偏移对指纹的影响:模拟 ±1~6 像素的行中心估算误差。 img = bot.capture_session_list() selected_y = bot.detect_selected_row(img) if selected_y >= 0: anchor = bot._raw_session_fingerprint(img, selected_y, row_center=True) print("\n[敏感度] 同一张图,仅把行中心挪动若干像素:") for offset in (1, 2, 3, 4, 6, 8): for sign in (-1, 1): shifted = bot._raw_session_fingerprint( img, selected_y + sign * offset, row_center=True, ) print( " 行中心 %+d px -> 头像漂移 %2d 位%s" % ( sign * offset, hamming(anchor, shifted), " 超出容差!" if hamming(anchor, shifted) > bot_module.WeChatBot._FP_HAMMING_TOL else "", ) ) if __name__ == "__main__": main()