Skip to content

Instantly share code, notes, and snippets.

View edamtoft's full-sized avatar

Eric Damtoft edamtoft

View GitHub Profile
@edamtoft
edamtoft / HexUtils.cs
Last active December 18, 2019 18:09
High Performance byte[] to Hex String Converter
public static class HexUtils
{
private const string HexAlphabet = "0123456789abcdef";
public static string ToHexString(byte[] bytes)
{
return string.Create(bytes.Length * 2, bytes, (chars, buffer) =>
{
var charIndex = 0;
var bufferIndex = 0;
@edamtoft
edamtoft / HexUtils.cs
Created December 18, 2019 17:22
High Performance byte[] to Hex String Converter.
public static class HexUtils
{
public static string ToHexString(byte[] bytes)
{
return string.Create(bytes.Length * 2, bytes, (chars, buffer) =>
{
for (var i = 0; i < buffer.Length; i += 2)
{
var b = buffer[i / 2];
chars[i] = GetHexChar(b / 16);
public static class Match
{
public static Matcher<T, TResult> From<T, TResult>() => new Matcher<T, TResult>();
}
public sealed class Matcher<T, TResult>
{
public TResult DefaultValue { get; set; }
public List<(TResult Value, Func<T,bool> Test)> Tests { get; } = new List<(TResult Value, Func<T,bool> Test)>();
@edamtoft
edamtoft / PasswordHasher.cs
Last active September 11, 2021 11:17
Password Hashing in .NET Core - Full Implementation
public sealed class PasswordHasher : IPasswordHasher
{
private const int SaltSize = 16; // 128 bit
private const int KeySize = 32; // 256 bit
public PasswordHasher(IOptions<HashingOptions> options)
{
Options = options.Value;
}
public (bool Verified, bool NeedsUpgrade) Check(string hash, string password)
{
var parts = hash.Split('.', 3);
if (parts.Length != 3)
{
throw new FormatException("Unexpected hash format. " +
"Should be formatted as `{iterations}.{salt}.{hash}`");
}
public string Hash(string password)
{
using (var algorithm = new Rfc2898DeriveBytes(
password,
SaltSize,
Options.Iterations,
HashAlgorithmName.SHA256))
{
var key = Convert.ToBase64String(algorithm.GetBytes(KeySize));
var salt = Convert.ToBase64String(algorithm.Salt);
public sealed class PasswordHasher : IPasswordHasher
{
private const int SaltSize = 16; // 128 bit
private const int KeySize = 32; // 256 bit
public PasswordHasher(IOptions<HashingOptions> options)
{
Options = options.Value;
}
public sealed class HashingOptions
{
public int Iterations { get; set; } = 10000;
}
@edamtoft
edamtoft / IPasswordHasher.cs
Last active March 27, 2019 18:21
IPasswordHasher Interface
public interface IPasswordHasher
{
string Hash(string password);
(bool Verified, bool NeedsUpgrade) Check(string hash, string password);
}
@edamtoft
edamtoft / IRateLimiter.cs
Last active February 20, 2019 15:52
Rate Limiting for X-Requests-per-Y-Timespan APIs
public interface IRateLimiter
{
Task<T> RunRateLimited<T>(Func<Task<T>> func);
}