Privacy Score — C# 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 C# implementation — the same logic the interactive tool runs, in a shareable, citable form.
// privacy-score — composite privacy scoring engine.
//
// Language: C# (.NET 8, no dependencies)
// 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.
using System;
using System.Collections.Generic;
using System.Linq;
namespace PrivacyScore;
public static class Scorer
{
// Round to the nearest point and pin into the 0..25 window.
private static int Clamp25(double points) =>
(int)Math.Clamp(Math.Round(points, MidpointRounding.AwayFromZero), 0, 25);
public static string StatusFor(int points) =>
points >= 20 ? "ok" : points >= 10 ? "warn" : "bad";
// 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.
public static int FingerprintPoints(int signalCount, int highRisk, int mediumRisk) =>
Clamp25(25 - highRisk * 4 - mediumRisk * 1.5 - Math.Max(0, signalCount - 12) * 0.5);
public static int PasswordPoints(int score, bool breached)
{
double basis = Math.Clamp(score, 0, 4) / 4.0 * 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 ? basis * 0.32 : basis);
}
public static int HeadersPoints(IReadOnlyList<char> grades)
{
if (grades.Contains('F')) return 0;
if (grades.Contains('C')) return 10;
if (grades.Contains('B')) return 18;
return grades.Count > 0 ? 25 : 0;
}
public static int BreachPoints(bool pwned) => pwned ? 0 : 25;
public static string LetterFor(int percent, int max) => max == 0 ? "—"
: percent >= 85 ? "A"
: percent >= 70 ? "B"
: percent >= 50 ? "C"
: "D";
// Renormalize over the checks that ran and grade the overall letter.
public static (int Total, int Max, int Percent, string Letter) Score(params int[] points)
{
int total = points.Sum();
int max = points.Length * 25;
int percent = max == 0
? 0
: (int)Math.Round(total * 100.0 / max, MidpointRounding.AwayFromZero);
return (total, max, percent, LetterFor(percent, max));
}
}
public static class Program
{
public static void Main()
{
int[] checks =
[
Scorer.FingerprintPoints(18, 2, 4), // 8
Scorer.PasswordPoints(4, breached: true), // 8 (breach floor)
Scorer.HeadersPoints(['A', 'A', 'B']), // 18
Scorer.BreachPoints(false), // 25
];
var (total, max, percent, letter) = Scorer.Score(checks);
Console.WriteLine($"total {total}/{max} = {percent}% -> {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 →