Skip to content

Checksum Verifier — C# source

Drag and drop a file to compute its MD5, SHA-1, SHA-256, and SHA-512 checksums. Paste an expected hash to verify integrity - detect tampered or corrupted downloads instantly. Runs entirely in your browser.

This is the C# implementation — the same logic the interactive tool runs, in a shareable, citable form.

// Checksum Verifier — MD5 / SHA-1 / SHA-256 / SHA-512 digests + verification.
// C# 12 / .NET 8 — ported from src/lib/checksum-verifier.ts (the canonical
// TypeScript implementation). Display source for CosmoDev's polyglot pages.
//
// The TS reference hand-rolls MD5 (RFC 1321) because the Web Crypto API does
// not ship it; .NET's standard library does, so every digest here is a one-line
// HashData call. The verification layer — length-based algorithm detection and
// pasted-hash normalization — ports unchanged.

using System.Text.RegularExpressions;

/// <summary>The four supported checksum algorithms.</summary>
public enum HashAlgorithm
{
    Md5,
    Sha1,
    Sha256,
    Sha512,
}

/// <summary>All four checksums of one buffer, as lowercase hex.</summary>
/// <param name="Md5">128-bit MD5 digest (integrity checks only — not security).</param>
/// <param name="Sha1">160-bit SHA-1 digest.</param>
/// <param name="Sha256">256-bit SHA-256 digest.</param>
/// <param name="Sha512">512-bit SHA-512 digest.</param>
public sealed record ChecksumResult(string Md5, string Sha1, string Sha256, string Sha512);

public static class ChecksumVerifier
{
    /// <summary>One-shot MD5 (integrity checks only — MD5 is broken for security).</summary>
    public static string Md5(byte[] data) =>
        Convert.ToHexString(System.Security.Cryptography.MD5.HashData(data)).ToLowerInvariant();

    /// <summary>One-shot SHA-1.</summary>
    public static string Sha1(byte[] data) =>
        Convert.ToHexString(System.Security.Cryptography.SHA1.HashData(data)).ToLowerInvariant();

    /// <summary>One-shot SHA-256.</summary>
    public static string Sha256(byte[] data) =>
        Convert.ToHexString(System.Security.Cryptography.SHA256.HashData(data)).ToLowerInvariant();

    /// <summary>One-shot SHA-512.</summary>
    public static string Sha512(byte[] data) =>
        Convert.ToHexString(System.Security.Cryptography.SHA512.HashData(data)).ToLowerInvariant();

    /// <summary>Compute all four checksums of a buffer.</summary>
    public static ChecksumResult ComputeChecksums(byte[] data) =>
        new(Md5(data), Sha1(data), Sha256(data), Sha512(data));

    // --- Verification helpers ---------------------------------------------------

    private static readonly Dictionary<int, HashAlgorithm> LengthToAlgo = new()
    {
        [32] = HashAlgorithm.Md5,
        [40] = HashAlgorithm.Sha1,
        [64] = HashAlgorithm.Sha256,
        [128] = HashAlgorithm.Sha512,
    };

    private static readonly Regex HexOnly = Compile(@"^[0-9a-f]+$");

    /// <summary>Normalize a pasted hash: drop whitespace and ":" grouping, lowercase.</summary>
    private static string NormalizeHash(string hash) =>
        Regex.Replace(hash.Trim(), @"[\s:]", "").ToLowerInvariant();

    /// <summary>
    /// Detect the algorithm from the hex length: 32=MD5, 40=SHA-1, 64=SHA-256,
    /// 128=SHA-512. Returns null for anything that is not a supported hex hash.
    /// </summary>
    public static HashAlgorithm? DetectHashAlgorithm(string hash)
    {
        var h = NormalizeHash(hash);
        if (!HexOnly.IsMatch(h)) return null;
        return LengthToAlgo.TryGetValue(h.Length, out var algo) ? algo : null;
    }

    /// <summary>
    /// Compare an expected hash against a computed result. Returns null when
    /// the expected string is not a recognizable hex hash of a supported length.
    /// </summary>
    public static (HashAlgorithm Algorithm, bool Match)? VerifyChecksum(string expected, ChecksumResult result)
    {
        var algorithm = DetectHashAlgorithm(expected);
        if (algorithm is null) return null;
        var computed = algorithm switch
        {
            HashAlgorithm.Md5 => result.Md5,
            HashAlgorithm.Sha1 => result.Sha1,
            HashAlgorithm.Sha256 => result.Sha256,
            HashAlgorithm.Sha512 => result.Sha512,
            _ => throw new ArgumentOutOfRangeException(nameof(algorithm)),
        };
        return (algorithm.Value, NormalizeHash(expected) == computed);
    }

    private static Regex Compile(string pattern) => new(pattern, RegexOptions.Compiled);
}

Also available in 8 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 →