<PackageReference Include="System.Memory" Version="4.5.2" />

Base64

public static class Base64
using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace System.Buffers.Text { public static class Base64 { private static readonly sbyte[] s_decodingMap = new sbyte[256] { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; private static readonly byte[] s_encodingMap = new byte[64] { 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47 }; private const byte EncodingPad = 61; private const int MaximumEncodeLength = 1610612733; public static OperationStatus DecodeFromUtf8(ReadOnlySpan<byte> utf8, Span<byte> bytes, out int bytesConsumed, out int bytesWritten, bool isFinalBlock = true) { ref byte reference = ref MemoryMarshal.GetReference(utf8); ref byte reference2 = ref MemoryMarshal.GetReference(bytes); int num = utf8.Length & -4; int length = bytes.Length; int num2 = 0; int num3 = 0; if (utf8.Length != 0) { ref sbyte reference3 = ref s_decodingMap[0]; int num4 = isFinalBlock ? 4 : 0; int num5 = 0; num5 = ((length < GetMaxDecodedFromUtf8Length(num)) ? (length / 3 * 4) : (num - num4)); while (true) { if (num2 < num5) { int num6 = Decode(ref Unsafe.Add(ref reference, num2), ref reference3); if (num6 >= 0) { WriteThreeLowOrderBytes(ref Unsafe.Add(ref reference2, num3), num6); num3 += 3; num2 += 4; continue; } } else { if (num5 != num - num4) goto IL_0205; if (num2 == num) { if (!isFinalBlock) { bytesConsumed = num2; bytesWritten = num3; return OperationStatus.NeedMoreData; } } else { int elementOffset = Unsafe.Add(ref reference, num - 4); int elementOffset2 = Unsafe.Add(ref reference, num - 3); int num7 = Unsafe.Add(ref reference, num - 2); int num8 = Unsafe.Add(ref reference, num - 1); elementOffset = Unsafe.Add(ref reference3, elementOffset); elementOffset2 = Unsafe.Add(ref reference3, elementOffset2); elementOffset <<= 18; elementOffset2 <<= 12; elementOffset |= elementOffset2; if (num8 != 61) { num7 = Unsafe.Add(ref reference3, num7); num8 = Unsafe.Add(ref reference3, num8); num7 <<= 6; elementOffset |= num8; elementOffset |= num7; if (elementOffset >= 0) { if (num3 <= length - 3) { WriteThreeLowOrderBytes(ref Unsafe.Add(ref reference2, num3), elementOffset); num3 += 3; goto IL_01eb; } goto IL_0205; } } else if (num7 != 61) { num7 = Unsafe.Add(ref reference3, num7); num7 <<= 6; elementOffset |= num7; if (elementOffset >= 0) { if (num3 <= length - 2) { Unsafe.Add(ref reference2, num3) = (byte)(elementOffset >> 16); Unsafe.Add(ref reference2, num3 + 1) = (byte)(elementOffset >> 8); num3 += 2; goto IL_01eb; } goto IL_0205; } } else if (elementOffset >= 0) { if (num3 <= length - 1) { Unsafe.Add(ref reference2, num3) = (byte)(elementOffset >> 16); num3++; goto IL_01eb; } goto IL_0205; } } } goto IL_022b; IL_01eb: num2 += 4; if (num == utf8.Length) break; goto IL_022b; IL_022b: bytesConsumed = num2; bytesWritten = num3; return OperationStatus.InvalidData; IL_0205: if (!((num != utf8.Length) & isFinalBlock)) { bytesConsumed = num2; bytesWritten = num3; return OperationStatus.DestinationTooSmall; } goto IL_022b; } } bytesConsumed = num2; bytesWritten = num3; return OperationStatus.Done; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetMaxDecodedFromUtf8Length(int length) { if (length < 0) System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length); return (length >> 2) * 3; } public static OperationStatus DecodeFromUtf8InPlace(Span<byte> buffer, out int bytesWritten) { int length = buffer.Length; int num = 0; int num2 = 0; if (length == (length >> 2) * 4) { if (length == 0) goto IL_016d; ref byte reference = ref MemoryMarshal.GetReference(buffer); ref sbyte reference2 = ref s_decodingMap[0]; while (num < length - 4) { int num3 = Decode(ref Unsafe.Add(ref reference, num), ref reference2); if (num3 >= 0) { WriteThreeLowOrderBytes(ref Unsafe.Add(ref reference, num2), num3); num2 += 3; num += 4; continue; } goto IL_0172; } int elementOffset = Unsafe.Add(ref reference, length - 4); int elementOffset2 = Unsafe.Add(ref reference, length - 3); int num4 = Unsafe.Add(ref reference, length - 2); int num5 = Unsafe.Add(ref reference, length - 1); elementOffset = Unsafe.Add(ref reference2, elementOffset); elementOffset2 = Unsafe.Add(ref reference2, elementOffset2); elementOffset <<= 18; elementOffset2 <<= 12; elementOffset |= elementOffset2; if (num5 != 61) { num4 = Unsafe.Add(ref reference2, num4); num5 = Unsafe.Add(ref reference2, num5); num4 <<= 6; elementOffset |= num5; elementOffset |= num4; if (elementOffset >= 0) { WriteThreeLowOrderBytes(ref Unsafe.Add(ref reference, num2), elementOffset); num2 += 3; goto IL_016d; } } else if (num4 != 61) { num4 = Unsafe.Add(ref reference2, num4); num4 <<= 6; elementOffset |= num4; if (elementOffset >= 0) { Unsafe.Add(ref reference, num2) = (byte)(elementOffset >> 16); Unsafe.Add(ref reference, num2 + 1) = (byte)(elementOffset >> 8); num2 += 2; goto IL_016d; } } else if (elementOffset >= 0) { Unsafe.Add(ref reference, num2) = (byte)(elementOffset >> 16); num2++; goto IL_016d; } } goto IL_0172; IL_016d: bytesWritten = num2; return OperationStatus.Done; IL_0172: bytesWritten = num2; return OperationStatus.InvalidData; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int Decode(ref byte encodedBytes, ref sbyte decodingMap) { int elementOffset = encodedBytes; int elementOffset2 = Unsafe.Add(ref encodedBytes, 1); int elementOffset3 = Unsafe.Add(ref encodedBytes, 2); int elementOffset4 = Unsafe.Add(ref encodedBytes, 3); elementOffset = Unsafe.Add(ref decodingMap, elementOffset); elementOffset2 = Unsafe.Add(ref decodingMap, elementOffset2); elementOffset3 = Unsafe.Add(ref decodingMap, elementOffset3); elementOffset4 = Unsafe.Add(ref decodingMap, elementOffset4); elementOffset <<= 18; elementOffset2 <<= 12; elementOffset3 <<= 6; elementOffset |= elementOffset4; elementOffset2 |= elementOffset3; return elementOffset | elementOffset2; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static void WriteThreeLowOrderBytes(ref byte destination, int value) { destination = (byte)(value >> 16); Unsafe.Add(ref destination, 1) = (byte)(value >> 8); Unsafe.Add(ref destination, 2) = (byte)value; } public static OperationStatus EncodeToUtf8(ReadOnlySpan<byte> bytes, Span<byte> utf8, out int bytesConsumed, out int bytesWritten, bool isFinalBlock = true) { ref byte reference = ref MemoryMarshal.GetReference(bytes); ref byte reference2 = ref MemoryMarshal.GetReference(utf8); int length = bytes.Length; int length2 = utf8.Length; int num = 0; num = ((length > 1610612733 || length2 < GetMaxEncodedToUtf8Length(length)) ? ((length2 >> 2) * 3 - 2) : (length - 2)); int i = 0; int num2 = 0; int num3 = 0; ref byte encodingMap = ref s_encodingMap[0]; for (; i < num; i += 3) { num3 = Encode(ref Unsafe.Add(ref reference, i), ref encodingMap); Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference2, num2), num3); num2 += 4; } if (num == length - 2) { if (isFinalBlock) { if (i == length - 1) { num3 = EncodeAndPadTwo(ref Unsafe.Add(ref reference, i), ref encodingMap); Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference2, num2), num3); num2 += 4; i++; } else if (i == length - 2) { num3 = EncodeAndPadOne(ref Unsafe.Add(ref reference, i), ref encodingMap); Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference2, num2), num3); num2 += 4; i += 2; } bytesConsumed = i; bytesWritten = num2; return OperationStatus.Done; } bytesConsumed = i; bytesWritten = num2; return OperationStatus.NeedMoreData; } bytesConsumed = i; bytesWritten = num2; return OperationStatus.DestinationTooSmall; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int GetMaxEncodedToUtf8Length(int length) { if ((uint)length > 1610612733) System.ThrowHelper.ThrowArgumentOutOfRangeException(System.ExceptionArgument.length); return (length + 2) / 3 * 4; } public static OperationStatus EncodeToUtf8InPlace(Span<byte> buffer, int dataLength, out int bytesWritten) { int maxEncodedToUtf8Length = GetMaxEncodedToUtf8Length(dataLength); if (buffer.Length >= maxEncodedToUtf8Length) { int num = dataLength - dataLength / 3 * 3; int num2 = maxEncodedToUtf8Length - 4; int num3 = dataLength - num; int num4 = 0; ref byte encodingMap = ref s_encodingMap[0]; ref byte reference = ref MemoryMarshal.GetReference(buffer); switch (num) { case 1: num4 = EncodeAndPadTwo(ref Unsafe.Add(ref reference, num3), ref encodingMap); Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num2), num4); num2 -= 4; break; default: num4 = EncodeAndPadOne(ref Unsafe.Add(ref reference, num3), ref encodingMap); Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num2), num4); num2 -= 4; break; case 0: break; } for (num3 -= 3; num3 >= 0; num3 -= 3) { num4 = Encode(ref Unsafe.Add(ref reference, num3), ref encodingMap); Unsafe.WriteUnaligned(ref Unsafe.Add(ref reference, num2), num4); num2 -= 4; } bytesWritten = maxEncodedToUtf8Length; return OperationStatus.Done; } bytesWritten = 0; return OperationStatus.DestinationTooSmall; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int Encode(ref byte threeBytes, ref byte encodingMap) { int num = (threeBytes << 16) | (Unsafe.Add(ref threeBytes, 1) << 8) | Unsafe.Add(ref threeBytes, 2); int num2 = Unsafe.Add(ref encodingMap, num >> 18); int num3 = Unsafe.Add(ref encodingMap, (num >> 12) & 63); int num4 = Unsafe.Add(ref encodingMap, (num >> 6) & 63); int num5 = Unsafe.Add(ref encodingMap, num & 63); return num2 | (num3 << 8) | (num4 << 16) | (num5 << 24); } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int EncodeAndPadOne(ref byte twoBytes, ref byte encodingMap) { int num = (twoBytes << 16) | (Unsafe.Add(ref twoBytes, 1) << 8); int num2 = Unsafe.Add(ref encodingMap, num >> 18); int num3 = Unsafe.Add(ref encodingMap, (num >> 12) & 63); int num4 = Unsafe.Add(ref encodingMap, (num >> 6) & 63); return num2 | (num3 << 8) | (num4 << 16) | 1023410176; } [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int EncodeAndPadTwo(ref byte oneByte, ref byte encodingMap) { int num = oneByte << 8; int num2 = Unsafe.Add(ref encodingMap, num >> 10); int num3 = Unsafe.Add(ref encodingMap, (num >> 4) & 63); return num2 | (num3 << 8) | 3997696 | 1023410176; } } }