修复虎牙国际手机号格式:按抓包使用 00+区号+本地号

香港号 +852… 应提交 00852…(非 0852…/裸 852…);同步支持印尼 62、英国 44 等国际号,大陆仍用 086。
This commit is contained in:
yml2213
2026-07-12 20:19:00 +08:00
parent 851d8c122b
commit b2619caa14
+60 -9
View File
@@ -154,9 +154,13 @@ class HuyaSmsCodeResult:
request_id: str = ""
def _split_country_calling_code(digits: str) -> tuple[str, str]:
"""从国际号码中拆出国家/地区区号。"""
for size in (3, 2, 1):
def _split_country_calling_code(digits: str, *, allow_single_digit: bool = True) -> tuple[str, str]:
"""从国际号码中拆出国家/地区区号。
allow_single_digit=False 时不匹配 1/7 等单位区号,避免把国内 1 开头手机号误判成美国号。
"""
sizes = (3, 2, 1) if allow_single_digit else (3, 2)
for size in sizes:
code = digits[:size]
if code in HUYA_COUNTRY_CALLING_CODES and len(digits) > size:
return code, digits[size:]
@@ -164,16 +168,33 @@ def _split_country_calling_code(digits: str) -> tuple[str, str]:
def _format_huya_international_phone(code: str, national_number: str) -> str:
"""转换成虎牙短信接口使用的三位区号格式。"""
return f"{code.zfill(3)}{national_number}"
"""转换成虎牙短信接口使用的国际号格式。
抓包(香港登录 HAR)确认:
+85291283650 → data.phone = \"0085291283650\"
即 00 + 区号 + 本地号。
中国大陆沿用历史格式:086 + 11 位手机号。
"""
code = str(code or "").strip().lstrip("0") or str(code or "").strip()
national_number = str(national_number or "").strip()
if not code or not national_number:
return f"{code}{national_number}"
# 中国大陆
if code == "86":
return f"086{national_number}"
# 国际号:00 + 国家/地区区号 + 本地号(美加 1 → 001…,香港 852 → 00852…)
return f"00{code}{national_number}"
def normalize_huya_phone(phone: str) -> str:
"""归一化虎牙短信接口手机号格式,兼容国内号和显式国际区号。"""
"""归一化虎牙短信接口手机号格式,兼容国内号和国际区号(含香港 +852"""
raw = str(phone or "").strip()
digits = "".join(ch for ch in raw if ch.isdigit())
if not digits:
return ""
# 显式国际号:+852… / 00852…
if raw.startswith("+"):
code, national_number = _split_country_calling_code(digits)
if code:
@@ -182,13 +203,43 @@ def normalize_huya_phone(phone: str) -> str:
code, national_number = _split_country_calling_code(digits[2:])
if code:
return _format_huya_international_phone(code, national_number)
# 已是正确虎牙格式
# - 国内 086 + 11 位
if digits.startswith("086") and len(digits) == 14:
return digits
if digits.startswith("0") and len(digits) > 11:
return digits
if digits.startswith("086"):
# - 国际 00 + 区号…(再走一遍规范化,兼容已是 00852…)
# 上面 00 分支已处理
# 错误的单 0 国际号(历史错误归一 0852…)→ 按 0 后内容重解析
if digits.startswith("0") and not digits.startswith("00") and len(digits) >= 12:
rest = digits[1:]
code, national_number = _split_country_calling_code(rest)
if code and code != "86" and len(national_number) >= 6:
return _format_huya_international_phone(code, national_number)
if digits.startswith("086"):
return digits
return digits
# 无 + 的裸国际号:
# - 3 位区号:852/886…
# - 2 位区号:仅当总长 > 10(印尼 62、英国 44),避免 10 位美国号被 20 误吃
if len(digits) >= 9:
code3 = digits[:3]
national3 = digits[3:]
if code3 in HUYA_COUNTRY_CALLING_CODES and len(national3) >= 6:
return _format_huya_international_phone(code3, national3)
if len(digits) > 10:
code2 = digits[:2]
national2 = digits[2:]
if code2 in HUYA_COUNTRY_CALLING_CODES and len(national2) >= 6:
return _format_huya_international_phone(code2, national2)
# 国内号
if digits.startswith("86") and len(digits) == 13:
return f"0{digits}"
if len(digits) == 11 and digits.startswith(("13", "14", "15", "16", "17", "18", "19")):
return f"086{digits}"
if len(digits) == 11:
return f"086{digits}"
if len(digits) == 10: