45 lines
1.2 KiB
Python
45 lines
1.2 KiB
Python
import re
|
|
|
|
VIN_RE = re.compile(r"^[A-HJ-NPR-Z0-9]{17}$")
|
|
|
|
|
|
def normalize_vin(value: str | None) -> str | None:
|
|
if not value:
|
|
return None
|
|
normalized = re.sub(r"[\s-]+", "", value).upper()
|
|
return normalized or None
|
|
|
|
|
|
def validate_vin(value: str | None) -> str | None:
|
|
normalized = normalize_vin(value)
|
|
if normalized is None:
|
|
return None
|
|
if not VIN_RE.match(normalized):
|
|
raise ValueError("VIN must contain 17 characters and cannot include I, O, or Q")
|
|
return normalized
|
|
|
|
|
|
def normalize_license_plate(value: str | None) -> str | None:
|
|
if not value:
|
|
return None
|
|
normalized = re.sub(r"[\s\-_.]+", "", value).upper()
|
|
return normalized or None
|
|
|
|
|
|
def mask_vin(value: str | None) -> str | None:
|
|
normalized = normalize_vin(value)
|
|
if not normalized:
|
|
return None
|
|
if len(normalized) <= 6:
|
|
return "*" * len(normalized)
|
|
return f"{normalized[:3]}{'*' * 10}{normalized[-4:]}"
|
|
|
|
|
|
def mask_license_plate(value: str | None) -> str | None:
|
|
normalized = normalize_license_plate(value)
|
|
if not normalized:
|
|
return None
|
|
if len(normalized) <= 3:
|
|
return "*" * len(normalized)
|
|
return f"{normalized[:2]}{'*' * max(len(normalized) - 4, 2)}{normalized[-2:]}"
|