HexEncoder
using System;
using System.IO;
namespace Org.BouncyCastle.Utilities.Encoders
{
public class HexEncoder : IEncoder
{
private static readonly char[] CharsLower = new char[16] {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f'
};
private static readonly char[] CharsUpper = new char[16] {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F'
};
protected readonly byte[] encodingTable = new byte[16] {
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
97,
98,
99,
100,
101,
102
};
protected readonly byte[] decodingTable = new byte[128];
internal static int EncodeLower(ReadOnlySpan<byte> input, Span<char> output)
{
int num = 0;
int length = input.Length;
int num2 = 0;
while (num < length) {
uint num4 = input[num++];
output[num2++] = CharsLower[num4 >> 4];
output[num2++] = CharsLower[num4 & 15];
}
return num2;
}
internal static int EncodeUpper(ReadOnlySpan<byte> input, Span<char> output)
{
int num = 0;
int length = input.Length;
int num2 = 0;
while (num < length) {
uint num4 = input[num++];
output[num2++] = CharsUpper[num4 >> 4];
output[num2++] = CharsUpper[num4 & 15];
}
return num2;
}
protected void InitialiseDecodingTable()
{
Arrays.Fill(decodingTable, byte.MaxValue);
for (int i = 0; i < encodingTable.Length; i++) {
decodingTable[encodingTable[i]] = (byte)i;
}
decodingTable[65] = decodingTable[97];
decodingTable[66] = decodingTable[98];
decodingTable[67] = decodingTable[99];
decodingTable[68] = decodingTable[100];
decodingTable[69] = decodingTable[101];
decodingTable[70] = decodingTable[102];
}
public HexEncoder()
{
InitialiseDecodingTable();
}
public int Encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff)
{
return Encode(inBuf.AsSpan(inOff, inLen), outBuf.AsSpan(outOff));
}
public int Encode(ReadOnlySpan<byte> input, Span<byte> output)
{
int num = 0;
int length = input.Length;
int num2 = 0;
while (num < length) {
uint num4 = input[num++];
output[num2++] = encodingTable[num4 >> 4];
output[num2++] = encodingTable[num4 & 15];
}
return num2;
}
public int Encode(byte[] buf, int off, int len, Stream outStream)
{
return Encode(buf.AsSpan(off, len), outStream);
}
public unsafe int Encode(ReadOnlySpan<byte> data, Stream outStream)
{
Span<byte> output = new Span<byte>(stackalloc byte[72], 72);
int result = data.Length * 2;
while (!data.IsEmpty) {
int num = System.Math.Min(36, data.Length);
int length = Encode(data.Slice(0, num), output);
outStream.Write(output.Slice(0, length));
int num2 = num;
data = data.Slice(num2, data.Length - num2);
}
return result;
}
private static bool Ignore(char c)
{
if (c != '\n' && c != '\r' && c != '\t')
return c == ' ';
return true;
}
public int Decode(byte[] data, int off, int length, Stream outStream)
{
return Decode(data.AsSpan(off, length), outStream);
}
public unsafe int Decode(ReadOnlySpan<byte> data, Stream outStream)
{
int num = 0;
Span<byte> span = new Span<byte>(stackalloc byte[36], 36);
int num2 = 0;
int num3 = data.Length;
while (num3 > 0 && Ignore((char)data[num3 - 1])) {
num3--;
}
int i = 0;
while (i < num3) {
for (; i < num3 && Ignore((char)data[i]); i++) {
}
byte b = decodingTable[data[i++]];
for (; i < num3 && Ignore((char)data[i]); i++) {
}
byte b2 = decodingTable[data[i++]];
if ((b | b2) >= 128)
throw new IOException("invalid characters encountered in Hex data");
span[num2++] = (byte)((b << 4) | b2);
if (num2 == span.Length) {
outStream.Write(span);
num2 = 0;
}
num++;
}
if (num2 > 0)
outStream.Write(span.Slice(0, num2));
return num;
}
public unsafe int DecodeString(string data, Stream outStream)
{
int num = 0;
Span<byte> span = new Span<byte>(stackalloc byte[36], 36);
int num2 = 0;
int num3 = data.Length;
while (num3 > 0 && Ignore(data[num3 - 1])) {
num3--;
}
int i = 0;
while (i < num3) {
for (; i < num3 && Ignore(data[i]); i++) {
}
byte b = decodingTable[data[i++]];
for (; i < num3 && Ignore(data[i]); i++) {
}
byte b2 = decodingTable[data[i++]];
if ((b | b2) >= 128)
throw new IOException("invalid characters encountered in Hex data");
span[num2++] = (byte)((b << 4) | b2);
if (num2 == span.Length) {
outStream.Write(span);
num2 = 0;
}
num++;
}
if (num2 > 0)
outStream.Write(span.Slice(0, num2));
return num;
}
internal byte[] DecodeStrict(string str, int off, int len)
{
if (str == null)
throw new ArgumentNullException("str");
if (off < 0 || len < 0 || off > str.Length - len)
throw new IndexOutOfRangeException("invalid offset and/or length specified");
if ((len & 1) != 0)
throw new ArgumentException("a hexadecimal encoding must have an even number of characters", "len");
int num = len >> 1;
byte[] array = new byte[num];
int num2 = off;
for (int i = 0; i < num; i++) {
byte b = decodingTable[str[num2++]];
byte b2 = decodingTable[str[num2++]];
if ((b | b2) >= 128)
throw new IOException("invalid characters encountered in Hex data");
array[i] = (byte)((b << 4) | b2);
}
return array;
}
}
}