Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0cf48241f9 |
@@ -6,13 +6,13 @@ feed 取最近的成功且省到钱的比价记录(脱敏用户名);不足 N 条
|
||||
种子是「生成规则」:用户名可空(空→随机合成脱敏名,避开同屏撞名)、金额是区间(每次随机取值)、
|
||||
feed 公平随机抽取(不看 sort_order),所有启用种子都有机会露出。
|
||||
|
||||
脱敏名规则(全 feed 统一,按字符算、中英文皆适用):
|
||||
- 有昵称 → 昵称脱敏:≥3 字「首+隐藏字数个星+末」(省钱小能手→省***手 / SaveKing→S******g),
|
||||
2 字「首+星」(阿强→阿*),1 字「用户+该字」(喵→用户喵);
|
||||
- 没昵称 → 合成一个假名(见下)再脱敏,少数露「用户+id 后 3 位」(用户********618)。
|
||||
真实条:设过昵称的按真实昵称脱敏;当前多数用户没设昵称,直接展示「用户****」会清一色,故给它们合成
|
||||
假名——后期真实昵称多了,真实条会直接用真实昵称,合成占比自然下降。种子 / 兜底同样合成、避开同屏撞名;
|
||||
种子留空 / 旧「用户****xxx」模板名一律重新合成(自愈历史种子,无需迁移)。
|
||||
脱敏名规则(对齐 PRD「用户标识打码规则」,按字符数算、中英文皆适用):
|
||||
- 有昵称 → 昵称脱敏:n≥5「首+***+末」(AAA省钱小能手→A***手 / Micky_ 毛→M***毛),
|
||||
n=4「首+**+末」(你好不好→你**好),n≤3「首+**」(小确呀→小** / 阿强→阿** / 喵→喵**);
|
||||
- 没昵称(真实用户)→「用户」+5星+id 后 2 位(用户*****08),按 user_id 稳定。
|
||||
真实条按上述 PRD 规则脱敏。种子 / 兜底无真实用户(无昵称/无 id,套不上「用户*****+id后2位」),
|
||||
仍本地合成多样假名再走同一套昵称脱敏(避开同屏撞名),让横条不至清一色;种子留空 / 旧「用户****xxx」
|
||||
模板名一律重新合成(自愈历史种子,无需迁移)。
|
||||
假名合成:纯本地语料**组合生成**(中文姓池×名字池 拼真名 / 中文网络昵称 / 英文昵称 / 英文名带数字尾),
|
||||
组合空间上万、中文为主英文为辅,脱敏后像真实异质用户群。**真实条按 `user_id` 播种确定性合成**(同一用户
|
||||
每次展示恒定、不同用户各异),刷新/翻页不变脸;种子 / 兜底用运行时随机源出多样填充。不依赖外部库。
|
||||
@@ -44,12 +44,12 @@ _REAL_ROWS_TTL_SECONDS = 30
|
||||
_REAL_ROWS_FETCH_CAP = 600 # 一次多取些,够 limit≤30 去重后取数;命中缓存后复用
|
||||
_real_rows_cache: dict = {"at": None, "rows": None}
|
||||
|
||||
# ===== 用户标识脱敏 + 没真实昵称时的假名合成 =====
|
||||
# 脱敏规则(中英文皆适用,按字符算):有昵称→≥3 字「首+隐藏字数个星+末」(省钱小能手→省***手 /
|
||||
# SaveKing→S******g)、2 字「首+星」(阿强→阿*)、1 字「用户+该字」(喵→用户喵);没昵称→用户+8星+id 后 3 位。
|
||||
# 没真实昵称时(当前多数用户 / 种子 / 兜底)合成假名:本地姓/名字池组合出真名 + 网络昵称语料(中/英)
|
||||
# 混播再走同一套脱敏,像真实异质用户群。后期真实昵称多了,真实条直接用真实昵称,这里占比自然下降。
|
||||
_ANON_STARS = "*" * 8 # 无昵称匿名串固定 8 星(用户********xxx)
|
||||
# ===== 用户标识脱敏(对齐 PRD) + 种子无真实昵称时的假名合成 =====
|
||||
# 脱敏规则(按字符数,中英文皆适用):有昵称→n≥5「首+***+末」、n=4「首+**+末」、n≤3「首+**」;
|
||||
# 没昵称(真实用户)→「用户」+5星+id 后 2 位(用户*****08)。
|
||||
# 种子/兜底没有真实用户(无昵称/无 id),本地用姓/名字池组合真名 + 网络昵称语料(中/英)合成假名,
|
||||
# 再走同一套昵称脱敏,让横条像真实异质用户群、不清一色(PRD 只约束真实用户,种子是运营填充)。
|
||||
_ANON_STARS = "*" * 5 # 「用户」匿名串固定 5 星(用户*****xx,对齐 PRD)
|
||||
|
||||
# 中文真名组合池:姓(百家姓常见 ~100)× 名字单字(~120)拼「姓 + 1~2 字」,组合空间上万。
|
||||
# 脱敏后只露「姓*」或「姓*末」,故无需真实姓名库——组合够多即看着各异(替代原 Faker zh_CN)。
|
||||
@@ -86,19 +86,23 @@ _NICK_EN = [
|
||||
|
||||
|
||||
def _mask_nickname(nick: str) -> str:
|
||||
"""昵称脱敏(按字符,中英文皆可):≥3 字→首+(隐藏字数个)星+末(省钱小能手→省***手 / SaveKing→S******g);
|
||||
2 字→首+星(阿强→阿*);1 字→「用户」+该字(喵→用户喵)。调用方需保证 nick 已 strip 且非空。"""
|
||||
"""昵称脱敏(按字符数,中英文皆可,对齐 PRD「用户标识打码规则」):
|
||||
n≥5 → 首+***+末(AAA省钱小能手→A***手 / Micky_ 毛→M***毛);
|
||||
n=4 → 首+**+末(你好不好→你**好 / Lady→L**y);
|
||||
n≤3 → 首+**(小确呀→小** / 阿强→阿** / 喵→喵** / Lay→L**)。
|
||||
调用方需保证 nick 已 strip 且非空。"""
|
||||
n = len(nick)
|
||||
if n >= 3:
|
||||
return nick[0] + "*" * (n - 2) + nick[-1]
|
||||
if n == 2:
|
||||
return nick[0] + "*"
|
||||
return "用户" + nick
|
||||
if n >= 5:
|
||||
return nick[0] + "***" + nick[-1]
|
||||
if n == 4:
|
||||
return nick[0] + "**" + nick[-1]
|
||||
return nick[0] + "**"
|
||||
|
||||
|
||||
def _anon_by_id(user_id: int) -> str:
|
||||
"""没昵称匿名:固定「用户」+ 8 星 + id 后 3 位(不足 3 位前补 0):用户********618。"""
|
||||
return "用户" + _ANON_STARS + f"{user_id % 1000:03d}"
|
||||
def _mask_anon(user_id: int) -> str:
|
||||
"""没昵称(真实用户,对齐 PRD):「用户」+ 5 星 + id 后 2 位(不足 2 位前补 0):用户*****08。
|
||||
注:user_id 为整数,「id 后 2 位」取末两位数字(PRD 示例「用户*****x8」的 x 为占位符)。"""
|
||||
return "用户" + _ANON_STARS + f"{user_id % 100:02d}"
|
||||
|
||||
|
||||
def _synth_full_name(rng: random.Random) -> str:
|
||||
@@ -118,27 +122,24 @@ def _synth_full_name(rng: random.Random) -> str:
|
||||
|
||||
|
||||
def _synth_masked_name(rng: random.Random) -> str:
|
||||
"""合成一条「已脱敏」假名(供没真实昵称的真实用户 / 种子 / 兜底用)。用传入 rng 决定一切随机。"""
|
||||
"""合成一条「已脱敏」假名(供种子 / 兜底用,真实用户已改走 PRD 规则)。用传入 rng 决定一切随机。"""
|
||||
full = _synth_full_name(rng).strip()
|
||||
return _mask_nickname(full) if full else "用户" + _ANON_STARS + f"{rng.randint(0, 999):03d}"
|
||||
return _mask_nickname(full) if full else "用户" + _ANON_STARS + f"{rng.randint(0, 99):02d}"
|
||||
|
||||
|
||||
def _mask_real(nickname: str | None, user_id: int) -> str:
|
||||
"""真实用户脱敏:设过昵称→昵称脱敏(中英文皆可);没昵称→**按 user_id 播种确定性合成假名**再脱敏
|
||||
(同一用户每次展示恒定、刷新不变脸,不同用户各异),避免无昵称用户清一色「用户****xxx」;
|
||||
少数(~15%)露「用户+真实 id 后 3 位」。当前多数用户没昵称,后期真实昵称多了占比下降。"""
|
||||
"""真实用户脱敏(对齐 PRD「用户标识打码规则」):设过昵称→昵称脱敏(中英文皆可);
|
||||
没昵称→「用户」+5星+id 后 2 位(用户*****08),按 user_id 稳定、刷新不变脸。"""
|
||||
nick = (nickname or "").strip()
|
||||
if nick:
|
||||
return _mask_nickname(nick)
|
||||
# 关键:按 user_id 播种本地 rng → 同一用户的合成名跨请求/刷新恒定(0.15 抽签也用它)。
|
||||
seeded = random.Random(user_id)
|
||||
return _anon_by_id(user_id) if seeded.random() < 0.15 else _synth_masked_name(seeded)
|
||||
return _mask_anon(user_id)
|
||||
|
||||
|
||||
def _synth_name(rng: random.Random) -> str:
|
||||
"""合成一条脱敏名(种子留空 / 旧模板名 / 兜底用):绝大多数=假名脱敏,少数=用户+随机 3 位(用户********618)。"""
|
||||
"""合成一条脱敏名(种子留空 / 旧模板名 / 兜底用):绝大多数=假名脱敏,少数=用户+随机 2 位(用户*****08)。"""
|
||||
if rng.random() < 0.15:
|
||||
return "用户" + _ANON_STARS + f"{rng.randint(0, 999):03d}"
|
||||
return "用户" + _ANON_STARS + f"{rng.randint(0, 99):02d}"
|
||||
return _synth_masked_name(rng)
|
||||
|
||||
|
||||
@@ -148,7 +149,7 @@ def _unique_name(used: set[str]) -> str:
|
||||
n = _synth_name(_rng)
|
||||
if n not in used:
|
||||
return n
|
||||
return "用户" + _ANON_STARS + f"{_rng.randint(0, 999):03d}" # 兜底:数字尾号天然好去重
|
||||
return "用户" + _ANON_STARS + f"{_rng.randint(0, 99):02d}" # 兜底:数字尾号天然好去重
|
||||
|
||||
|
||||
def _validate_amount(min_cents: int, max_cents: int) -> None:
|
||||
|
||||
Reference in New Issue
Block a user