Skip to content

Instantly share code, notes, and snippets.

@usausa
Last active December 3, 2022 05:38
Show Gist options
  • Save usausa/f06e9bdd3ed1de140ad11b86056fb007 to your computer and use it in GitHub Desktop.
Save usausa/f06e9bdd3ed1de140ad11b86056fb007 to your computer and use it in GitHub Desktop.
public static class HexEncoder
{
private static ReadOnlySpan<byte> HexTable => new[]
{
(byte)'0', (byte)'1', (byte)'2', (byte)'3',
(byte)'4', (byte)'5', (byte)'6', (byte)'7',
(byte)'8', (byte)'9', (byte)'A', (byte)'B',
(byte)'C', (byte)'D', (byte)'E', (byte)'F'
};
[SkipLocalsInit]
public static unsafe string Encode(ReadOnlySpan<byte> bytes)
{
var length = bytes.Length * 2;
var span = length < 512 ? stackalloc char[length] : new char[length];
ref var buffer = ref MemoryMarshal.GetReference(span);
ref var hex = ref MemoryMarshal.GetReference(HexTable);
for (var i = 0; i < bytes.Length; i++)
{
var b = bytes[i];
buffer = (char)Unsafe.Add(ref hex, b >> 4);
buffer = ref Unsafe.Add(ref buffer, 1);
buffer = (char)Unsafe.Add(ref hex, b & 0xF);
buffer = ref Unsafe.Add(ref buffer, 1);
}
return new string(span);
}
public static string Encode2(ReadOnlyMemory<byte> source) =>
String.Create(source.Length * 2, source, static (span, src) =>
{
ref var buffer = ref MemoryMarshal.GetReference(span);
ref var hex = ref MemoryMarshal.GetReference(HexTable);
var bytes = src.Span;
for (var i = 0; i < bytes.Length; i++)
{
var b = bytes[i];
buffer = (char)Unsafe.Add(ref hex, b >> 4);
buffer = ref Unsafe.Add(ref buffer, 1);
buffer = (char)Unsafe.Add(ref hex, b & 0xF);
buffer = ref Unsafe.Add(ref buffer, 1);
}
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment