Privacy Score — Kotlin 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 Kotlin implementation — the same logic the interactive tool runs, in a shareable, citable form.
// privacy-score — composite privacy scoring engine.
//
// Language: Kotlin (2.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.
import kotlin.math.max
import kotlin.math.roundToInt
/** Round to the nearest point and pin into the 0..25 window. */
fun clamp25(points: Double): Int = points.roundToInt().coerceIn(0, 25)
enum class Grade { A, B, C, F }
/** 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. */
fun fingerprintPoints(signalCount: Int, highRisk: Int, mediumRisk: Int): Int {
val surface = max(0, signalCount - 12) * 0.5
return clamp25(25.0 - highRisk * 4.0 - mediumRisk * 1.5 - surface)
}
fun passwordPoints(score: Int, breached: Boolean): Int {
val base = score.coerceIn(0, 4) / 4.0 * 25.0
// Breached is urgent regardless of strength: x0.32 floors even a
// score-4 password at 8 points -> "bad" -> the change-it recommendation.
return clamp25(if (breached) base * 0.32 else base)
}
fun headersPoints(grades: List<Grade>): Int = when {
Grade.F in grades -> 0
Grade.C in grades -> 10
Grade.B in grades -> 18
grades.isNotEmpty() -> 25
else -> 0
}
fun breachPoints(pwned: Boolean): Int = if (pwned) 0 else 25
fun letterFor(percent: Int, max: Int): String = when {
max == 0 -> "—"
percent >= 85 -> "A"
percent >= 70 -> "B"
percent >= 50 -> "C"
else -> "D"
}
/** Renormalize over the checks that ran and grade the overall letter. */
fun scorePrivacy(vararg points: Int): String {
val total = points.sum()
val max = points.size * 25
val percent = if (max == 0) 0 else (total.toDouble() / max * 100).roundToInt()
return "total $total/$max = $percent% -> ${letterFor(percent, max)}"
}
fun main() {
val report = scorePrivacy(
fingerprintPoints(signalCount = 18, highRisk = 2, mediumRisk = 4), // 8
passwordPoints(score = 4, breached = true), // 8 (breach floor)
headersPoints(listOf(Grade.A, Grade.A, Grade.B)), // 18
breachPoints(pwned = false), // 25
)
println(report)
}
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 →