Privacy Score — Swift 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 Swift implementation — the same logic the interactive tool runs, in a shareable, citable form.
// privacy-score — composite privacy scoring engine.
//
// Language: Swift (5.x, 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.
/// Header grade from a security-headers scan.
enum Grade: Character {
case a = "A", b = "B", c = "C", f = "F"
}
/// Round to the nearest point and pin into the 0...25 window.
func clamp25(_ points: Double) -> Int {
min(25, max(0, Int(points.rounded())))
}
/// 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.
func fingerprintPoints(signalCount: Int, highRisk: Int, mediumRisk: Int) -> Int {
let surface = Double(max(0, signalCount - 12)) * 0.5
return clamp25(25 - Double(highRisk) * 4 - Double(mediumRisk) * 1.5 - surface)
}
func passwordPoints(score: Int, breached: Bool) -> Int {
let base = Double(min(4, max(0, 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(breached ? base * 0.32 : base)
}
func headersPoints(_ grades: [Grade]) -> Int {
if grades.contains(.f) { return 0 }
if grades.contains(.c) { return 10 }
if grades.contains(.b) { return 18 }
return grades.isEmpty ? 0 : 25
}
func breachPoints(pwned: Bool) -> Int {
pwned ? 0 : 25
}
func letterFor(percent: Int, max: Int) -> String {
if max == 0 { return "—" }
if percent >= 85 { return "A" }
if percent >= 70 { return "B" }
if percent >= 50 { return "C" }
return "D"
}
/// Renormalize over the checks that ran and grade the overall letter.
func scorePrivacy(_ points: [Int]) -> (total: Int, max: Int, percent: Int, letter: String) {
let total = points.reduce(0, +)
let max = points.count * 25
let percent = max == 0 ? 0 : Int((Double(total) / Double(max) * 100).rounded())
return (total, max, percent, letterFor(percent: percent, max: max))
}
let checks = [
fingerprintPoints(signalCount: 18, highRisk: 2, mediumRisk: 4), // 8
passwordPoints(score: 4, breached: true), // 8 (breach floor)
headersPoints([.a, .a, .b]), // 18
breachPoints(pwned: false), // 25
]
let result = scorePrivacy(checks)
print("checks:", checks)
print("total \(result.total)/\(result.max) = \(result.percent)% -> \(result.letter)")
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 →