Skip to content

Privacy Score — Java 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 Java implementation — the same logic the interactive tool runs, in a shareable, citable form.

// privacy-score — composite privacy scoring engine.
//
// Language: Java (17+, 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 java.util.List;

public final class PrivacyScore {

    /** Round to the nearest point and pin into the 0..25 window. */
    private static int clamp25(double points) {
        return (int) Math.max(0, Math.min(25, Math.round(points)));
    }

    /**
     * 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) {
        double surface = Math.max(0, signalCount - 12) * 0.5;
        return clamp25(25.0 - highRisk * 4.0 - mediumRisk * 1.5 - surface);
    }

    public static int passwordPoints(int score, boolean breached) {
        double base = Math.max(0, Math.min(4, score)) / 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(breached ? base * 0.32 : base);
    }

    public static int headersPoints(List<Character> grades) {
        if (grades.contains('F')) return 0;
        if (grades.contains('C')) return 10;
        if (grades.contains('B')) return 18;
        return grades.isEmpty() ? 0 : 25;
    }

    public static int breachPoints(boolean pwned) {
        return pwned ? 0 : 25;
    }

    public static String letterFor(int percent, int max) {
        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. */
    public record Result(int total, int max, int percent, String letter) {}

    public static Result scorePrivacy(int... points) {
        int total = 0;
        for (int p : points) total += p;
        int max = points.length * 25;
        int percent = max == 0 ? 0 : (int) Math.round(total * 100.0 / max);
        return new Result(total, max, percent, letterFor(percent, max));
    }

    public static void main(String[] args) {
        Result r = scorePrivacy(
                fingerprintPoints(18, 2, 4),                // 8
                passwordPoints(4, true),                    // 8 (breach floor)
                headersPoints(List.of('A', 'A', 'B')),      // 18
                breachPoints(false));                       // 25
        System.out.println("total %d/%d = %d%% -> %s".formatted(
                r.total(), r.max(), r.percent(), r.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 →