o2o-plagiarism-ai/app/engine/training_data.py

39 lines
1.5 KiB
Python

"""수령 원고의 익명화와 학습 그룹 식별에 쓰는 공통 유틸리티."""
from __future__ import annotations
import hashlib
import hmac
import re
_EMAIL_RE = re.compile(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}")
_PHONE_RE = re.compile(r"(?<!\d)(?:01[016789]|0\d{1,2})[- .]?\d{3,4}[- .]?\d{4}(?!\d)")
_RRN_RE = re.compile(r"(?<!\d)\d{6}[- ]?[1-4]\d{6}(?!\d)")
def pseudonymous_id(value: str, salt: str, *, prefix: str = "author") -> str:
"""비밀 salt를 사용해 원래 식별자를 복원하기 어려운 안정 ID를 만든다."""
if not value.strip():
raise ValueError("익명화할 식별자가 비어 있습니다")
if not salt:
raise ValueError("익명화 salt가 비어 있습니다")
digest = hmac.new(
salt.encode("utf-8"), value.strip().encode("utf-8"), hashlib.sha256,
).hexdigest()[:24]
return f"{prefix}:{digest}"
def redact_direct_identifiers(text: str) -> str:
"""이메일·전화번호·주민번호처럼 직접 식별 가능한 문자열을 제거한다."""
value = _EMAIL_RE.sub("[EMAIL]", str(text))
value = _PHONE_RE.sub("[PHONE]", value)
return _RRN_RE.sub("[ID_NUMBER]", value)
def sanitize_prompt_metadata(value: str) -> str:
"""외부 생성 프롬프트에 넣기 전 직접 식별자와 제목 속 이름을 제거한다."""
cleaned = redact_direct_identifiers(value).strip()
cleaned = re.sub(r"^[가-힣]{2,4}의\s*자서전$", "익명 작성자의 자서전", cleaned)
return cleaned