Privacy Score — Python source
One number for your privacy health: your browser fingerprint, a test password's strength and breach exposure, and a site's security headers — four checks, one score, concrete fixes. Runs in your browser; only a 5-character hash prefix ever leaves it.
This is the Python implementation — the same logic the interactive tool runs, in a shareable, citable form.
"""privacy-score — composite privacy scoring engine.
Language: Python (3.9+, standard library only)
Source: CosmoDev polyglot showcase port of the Privacy Score tool,
ported from src/lib/privacy-score.ts (canonical TypeScript).
License: display source — part of CosmoDev's polyglot tool pages.
Four category checks, each scored out of 25; the overall percent is
renormalized over the categories that actually ran — skipping a check
never lowers your score. Letter bands: >=85 A, >=70 B, >=50 C, else D.
"""
from __future__ import annotations
def clamp25(points: float) -> int:
"""Round to the nearest point and pin into the 0..25 window."""
return max(0, min(25, round(points)))
def status_for(points: int) -> str:
return "ok" if points >= 20 else "warn" if points >= 10 else "bad"
def fingerprint_points(signal_count: int, high: int, medium: int) -> int:
# More distinguishable signals make a browser more unique: high-risk
# signals cost 4 each, medium 1.5, and a large surface costs a little more.
surface = max(0, signal_count - 12) * 0.5
return clamp25(25 - high * 4 - medium * 1.5 - surface)
def password_points(score: int, breached: bool) -> int:
base = max(0, min(4, score)) / 4 * 25
# Breached is urgent regardless of strength: x0.32 floors even a
# score-4 password at 8 points -> "bad" -> the change-it recommendation.
return clamp25(base * 0.32 if breached else base)
def headers_points(grades: list[str]) -> int:
counts = {g: grades.count(g) for g in "ABCF"}
if counts["F"] > 0:
return 0
if counts["C"] > 0:
return 10
if counts["B"] > 0:
return 18
return 25 if grades else 0
def breach_points(pwned: bool) -> int:
return 0 if pwned else 25
def letter_for(percent: int, maximum: int) -> str:
return ("—" if maximum == 0 else "A" if percent >= 85 else "B"
if percent >= 70 else "C" if percent >= 50 else "D")
def score_privacy(points: list[int]) -> dict:
"""Renormalize over the checks that ran and grade the overall letter."""
total = sum(points)
maximum = len(points) * 25
percent = round(total / maximum * 100) if maximum else 0
return {
"total": total, "max": maximum, "percent": percent,
"letter": letter_for(percent, maximum),
"statuses": [status_for(p) for p in points],
}
if __name__ == "__main__":
checks = [
fingerprint_points(signal_count=18, high=2, medium=4), # 8
password_points(score=4, breached=True), # 8 (breach floor)
headers_points(list("AAB")), # 18
breach_points(pwned=False), # 25
]
print(checks)
print(score_privacy(checks))
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →