using System;
using System.Diagnostics;
using System.IO;
namespace Org.BouncyCastle.Utilities.Encoders
{
///
/// Class to decode and encode Hex.
///
// TODO[api] Make static
public sealed class Hex
{
private static readonly HexEncoder encoder = new HexEncoder();
private Hex()
{
}
public static string ToHexString(byte[] data)
{
return ToHexString(data, false);
}
public static string ToHexString(byte[] data, bool upperCase)
{
return ToHexString(data, 0, data.Length, upperCase);
}
public static string ToHexString(byte[] data, int off, int length)
{
return ToHexString(data, off, length, false);
}
public static string ToHexString(byte[] data, int off, int length, bool upperCase)
{
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
return ToHexString(data.AsMemory(off, length), upperCase);
#else
byte[] hex = Encode(data, off, length);
var result = Strings.FromAsciiByteArray(hex);
if (upperCase)
{
result = result.ToUpperInvariant();
}
return result;
#endif
}
#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
public static string ToHexString(ReadOnlyMemory data, bool upperCase = false)
{
if (data.Length == 0)
return string.Empty;
if (data.Length > int.MaxValue / 2)
throw new ArgumentOutOfRangeException(nameof(data));
if (upperCase)
{
return string.Create(data.Length * 2, data, (chars, data) =>
{
int length = HexEncoder.EncodeUpper(data.Span, chars);
Debug.Assert(chars.Length == length);
});
}
else
{
return string.Create(data.Length * 2, data, (chars, data) =>
{
int length = HexEncoder.EncodeLower(data.Span, chars);
Debug.Assert(chars.Length == length);
});
}
}
#endif
/**
* encode the input data producing a Hex encoded byte array.
*
* @return a byte array containing the Hex encoded data.
*/
public static byte[] Encode(
byte[] data)
{
return Encode(data, 0, data.Length);
}
/**
* encode the input data producing a Hex encoded byte array.
*
* @return a byte array containing the Hex encoded data.
*/
public static byte[] Encode(
byte[] data,
int off,
int length)
{
MemoryStream bOut = new MemoryStream(length * 2);
encoder.Encode(data, off, length, bOut);
return bOut.ToArray();
}
/**
* Hex encode the byte data writing it to the given output stream.
*
* @return the number of bytes produced.
*/
public static int Encode(
byte[] data,
Stream outStream)
{
return encoder.Encode(data, 0, data.Length, outStream);
}
/**
* Hex encode the byte data writing it to the given output stream.
*
* @return the number of bytes produced.
*/
public static int Encode(
byte[] data,
int off,
int length,
Stream outStream)
{
return encoder.Encode(data, off, length, outStream);
}
/**
* decode the Hex encoded input data. It is assumed the input data is valid.
*
* @return a byte array representing the decoded data.
*/
public static byte[] Decode(
byte[] data)
{
MemoryStream bOut = new MemoryStream((data.Length + 1) / 2);
encoder.Decode(data, 0, data.Length, bOut);
return bOut.ToArray();
}
/**
* decode the Hex encoded string data - whitespace will be ignored.
*
* @return a byte array representing the decoded data.
*/
public static byte[] Decode(
string data)
{
MemoryStream bOut = new MemoryStream((data.Length + 1) / 2);
encoder.DecodeString(data, bOut);
return bOut.ToArray();
}
/**
* decode the Hex encoded string data writing it to the given output stream,
* whitespace characters will be ignored.
*
* @return the number of bytes produced.
*/
public static int Decode(
string data,
Stream outStream)
{
return encoder.DecodeString(data, outStream);
}
/**
* Decode the hexadecimal-encoded string strictly i.e. any non-hexadecimal characters will be
* considered an error.
*
* @return a byte array representing the decoded data.
*/
public static byte[] DecodeStrict(string str)
{
return encoder.DecodeStrict(str, 0, str.Length);
}
/**
* Decode the hexadecimal-encoded string strictly i.e. any non-hexadecimal characters will be
* considered an error.
*
* @return a byte array representing the decoded data.
*/
public static byte[] DecodeStrict(string str, int off, int len)
{
return encoder.DecodeStrict(str, off, len);
}
}
}