Apricot Framework

Usage

Worked examples for Crypto, Rnd and UrlExt.

Everything lives in the ApricotFramework.CoreUtility namespace.

using ApricotFramework.CoreUtility;

Crypto — URL-safe hashing

Two extension methods on string, intended for values that end up in a URL, a cache key, or a database column.

var sha256 = "hello".ToSafeSha256();
// LPJNul-wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ=

var sha512 = "hello".ToSafeSha512();
// m3HSJL1i83hdltRq0-o9czGb-8KJDKra4t_3JRlnPKcjI8PZm6XBHXx6zG4UuMXaDEZjR1wuXDre9G9zvN7AQw==

Both return string.Empty rather than throwing when the input is null, empty, or whitespace:

((string?)null).ToSafeSha256();   // ""
"".ToSafeSha256();               // ""
"   ".ToSafeSha256();            // ""

The encoding, precisely

The output is standard Base64 with the two URL-unsafe characters substituted:

Base64Output
+-
/_
== (retained)

Because padding is retained, this is not strictly base64url as defined by RFC 4648 §5. That is intentional. These values are routinely persisted, so changing the encoding would invalidate stored data — it is treated as a compatibility contract and pinned by golden-value tests.

Warning

These are plain cryptographic hashes with no salt and no key stretching. They are suitable for content addressing, cache keys, and integrity checks. They are not suitable for storing passwords — use a purpose-built KDF such as PBKDF2, bcrypt, scrypt, or Argon2 for that.

Rnd — cryptographically strong random strings

var token = Rnd.GetString(32);
// e.g. "hLp0QwZ3nT8kVyB1cRdX7sMgJ4aE6uNi"

Backed by RandomNumberGenerator, not System.Random, so the output is suitable for tokens and identifiers. The charset is [a-zA-Z0-9] — 62 characters — which makes the result safe to drop into a URL, a header, or a filename without escaping.

GetString(0) returns an empty string.

Note

Characters are selected by modulo over the 62-character set, which gives a very slight bias toward the first few characters (62 does not divide 2³²). It is immaterial for identifiers and tokens, but the distribution is not exactly uniform.

UrlExt — URL helpers

UrlExt.EnsureSlash("https://example.com/api");   // https://example.com/api/
UrlExt.EnsureSlash("https://example.com/api/");  // https://example.com/api/ (unchanged)

Useful when composing a base address for HttpClient, which silently discards the last path segment if the base address has no trailing slash:

// Without the trailing slash, "v1/users" resolves against ".../api", not ".../api/"
var client = new HttpClient
{
    BaseAddress = new Uri(UrlExt.EnsureSlash(options.ApiRoot))
};

EnsureSlash throws NullReferenceException if url is null. The parameter is declared non-nullable, so with nullable reference types enabled the compiler will warn you at the call site.

On this page