Basic Auth Generator — C# source
Build HTTP Basic Access Authentication headers from a username and password, or decode an existing Authorization header back to its credentials. UTF-8 safe and fully client-side, with a shareable link.
This is the C# implementation — the same logic the interactive tool runs, in a shareable, citable form.
// basic-auth-generator — HTTP Basic-Auth header encode/decode.
//
// Language: C# (12, .NET 8, standard library only)
// Source: CosmoDev polyglot showcase port of the Basic Auth Generator tool,
// ported from src/lib/basic-auth.ts (the canonical TypeScript
// implementation) and kept in lock-step with cli/basic-auth-generator.
// License: display source — part of CosmoDev's polyglot tool pages.
//
// Design goals:
// - Pure + deterministic; never throws (ParseHeader returns null on
// malformed input).
// - Functionally equivalent to the TS reference + Go twin: same inputs ->
// same outputs, same reject behavior on malformed headers.
// - Self-contained: the base class library only (System.Convert base64 +
// System.Text.UTF8Encoding).
//
// C# is a dependency-rich polyglot here, like the Python port: the BCL ships
// an RFC 4648 standard codec that matches Go's base64.StdEncoding. Two BCL
// quirks are compensated for below — Convert.FromBase64String treats padding
// as optional, and Encoding.UTF8.GetString silently replaces invalid byte
// sequences with U+FFFD — so both get the strict Go-equivalent behavior.
using System;
using System.Linq;
using System.Text;
namespace CosmoDev.Snippets;
/// <summary>A parsed username/password pair. Mirrors the Go twin's
/// <c>Credentials</c> struct and the TS <c>BasicAuthCredentials</c> interface.</summary>
public sealed record Credentials(string User, string Pass);
public static class BasicAuth
{
/// <summary>UTF-8 encoding that throws on invalid sequences instead of
/// replacing them with U+FFFD — the Go/Rust twins reject invalid UTF-8,
/// so this port does too.</summary>
private static readonly UTF8Encoding Utf8Strict =
new(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
/// <summary>Build an HTTP Basic-Auth header value:
/// <c>"Basic " + base64(user:pass)</c>. Mirrors <c>BuildHeader</c> in the
/// Go twin and <c>buildBasicAuth</c> in the TS source. The UTF-8 byte
/// representation is encoded, so multibyte credentials (e.g.
/// <c>café:päss</c>) work.</summary>
public static string BuildHeader(string user, string pass)
{
byte[] raw = Utf8Strict.GetBytes(user + ":" + pass);
return "Basic " + Convert.ToBase64String(raw);
}
/// <summary>Parse a <c>"Basic <token>"</c> header back into
/// credentials, or <c>null</c> if the header is malformed or the
/// credentials have no colon separator. Logic mirrors <c>ParseHeader</c>
/// in the Go twin exactly: trim the header, require a case-insensitive
/// <c>"basic "</c> prefix, trim the remaining token, base64-decode it
/// (rejecting invalid characters), then split on the FIRST colon so a
/// password containing colons round-trips.</summary>
public static Credentials? ParseHeader(string header)
{
string h = header.Trim();
if (!h.StartsWith("Basic ", StringComparison.OrdinalIgnoreCase))
{
return null;
}
string token = h[6..].Trim();
// FromBase64String ignores whitespace but treats '=' padding as
// optional; strip whitespace and enforce the multiple-of-4 length
// ourselves so malformed tokens are rejected like Go's StdEncoding.
string compact = string.Concat(token.Where(c => !char.IsWhiteSpace(c)));
if (compact.Length % 4 != 0)
{
return null;
}
byte[] decoded;
try
{
decoded = Convert.FromBase64String(compact);
}
catch (FormatException)
{
return null;
}
string text;
try
{
text = Utf8Strict.GetString(decoded);
}
catch (DecoderFallbackException)
{
return null;
}
int colon = text.IndexOf(':');
return colon < 0 ? null : new Credentials(text[..colon], text[(colon + 1)..]);
}
}
#if BASIC_AUTH_DEMO
// Showcase-only demo (the canonical suite lives in src/lib): compile with
// -define:BASIC_AUTH_DEMO to run the same vectors as the Rust port.
public static class BasicAuthDemo
{
public static void Main()
{
string h = BasicAuth.BuildHeader("user", "pass");
System.Diagnostics.Debug.Assert(h == "Basic dXNlcjpwYXNz");
Console.WriteLine(h);
(string User, string Pass)[] roundTrips =
{
("alice", "s3cr3t"), ("", "x"), ("x", ""), ("u", "a:b:c"),
};
foreach (var (user, pass) in roundTrips)
{
Credentials c = BasicAuth.ParseHeader(BasicAuth.BuildHeader(user, pass))!;
System.Diagnostics.Debug.Assert(c.User == user);
System.Diagnostics.Debug.Assert(c.Pass == pass); // colon-bearing password intact
}
string[] malformed = { "Bearer xyz", "", "Basic !!!not-base64!!!", "Basic bm9jb2xvbg==" };
foreach (string bad in malformed)
{
System.Diagnostics.Debug.Assert(BasicAuth.ParseHeader(bad) is null);
}
Console.WriteLine("all basic-auth-generator demo checks passed");
}
}
#endif
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 →