167 lines
6.1 KiB
C#
167 lines
6.1 KiB
C#
|
|
using System;
|
||
|
|
using System.Text;
|
||
|
|
|
||
|
|
namespace DTS.Common.Utilities
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// Summary description for HexEncoding.
|
||
|
|
/// </summary>
|
||
|
|
/// <remarks>This class has only static methods and appears to never be instantiated,
|
||
|
|
/// so I'm marking it static as well
|
||
|
|
/// there are built in classes for encoding and converting hex as well, but the behavior
|
||
|
|
/// here may deviate slightly
|
||
|
|
/// </remarks>
|
||
|
|
public static class HexEncoding
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// returns the number of bytes needed to represent hex string
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="hexString">hex string to calculate</param>
|
||
|
|
/// <returns>number of bytes</returns>
|
||
|
|
/// <remarks>doesn't count non hex characters
|
||
|
|
/// odd number of characters, last character is discarded
|
||
|
|
/// </remarks>
|
||
|
|
public static int GetByteCount(string hexString)
|
||
|
|
{
|
||
|
|
var numHexChars = 0;
|
||
|
|
char c;
|
||
|
|
// remove all none A-F, 0-9, characters
|
||
|
|
for (var i = 0; i < hexString.Length; i++)
|
||
|
|
{
|
||
|
|
c = hexString[i];
|
||
|
|
if (IsHexDigit(c))
|
||
|
|
numHexChars++;
|
||
|
|
}
|
||
|
|
// if odd number of characters, discard last character
|
||
|
|
if (numHexChars % 2 != 0)
|
||
|
|
{
|
||
|
|
numHexChars--;
|
||
|
|
}
|
||
|
|
return numHexChars / 2; // 2 characters per byte
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// Creates a byte array from the hexadecimal string. Each two characters are combined
|
||
|
|
/// to create one byte. First two hexadecimal characters become first byte in returned array.
|
||
|
|
/// Non-hexadecimal characters are ignored.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="hexString">string to convert to byte array</param>
|
||
|
|
/// <param name="discarded">number of characters in string ignored</param>
|
||
|
|
/// <returns>byte array, in the same left-to-right order as the hexString</returns>
|
||
|
|
public static byte[] GetBytes(string hexString, out int discarded)
|
||
|
|
{
|
||
|
|
discarded = 0;
|
||
|
|
var newString = "";
|
||
|
|
char c;
|
||
|
|
// remove all none A-F, 0-9, characters
|
||
|
|
for (var i = 0; i < hexString.Length; i++)
|
||
|
|
{
|
||
|
|
c = hexString[i];
|
||
|
|
if (IsHexDigit(c))
|
||
|
|
newString += c;
|
||
|
|
else
|
||
|
|
discarded++;
|
||
|
|
}
|
||
|
|
// if odd number of characters, discard last character
|
||
|
|
if (newString.Length % 2 != 0)
|
||
|
|
{
|
||
|
|
discarded++;
|
||
|
|
newString = newString.Substring(0, newString.Length - 1);
|
||
|
|
}
|
||
|
|
|
||
|
|
var byteLength = newString.Length / 2;
|
||
|
|
var bytes = new byte[byteLength];
|
||
|
|
string hex;
|
||
|
|
var j = 0;
|
||
|
|
for (var i = 0; i < bytes.Length; i++)
|
||
|
|
{
|
||
|
|
hex = new String(new Char[] { newString[j], newString[j + 1] });
|
||
|
|
bytes[i] = HexToByte(hex);
|
||
|
|
j = j + 2;
|
||
|
|
}
|
||
|
|
return bytes;
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// returns a string representation out of byte array
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="bytes">an array of hex characters packed 2 per byte</param>
|
||
|
|
/// <returns>string representation of hex characters in byte array, no spaces between bytes</returns>
|
||
|
|
public static string ToString(byte[] bytes)
|
||
|
|
{
|
||
|
|
var hexString = "";
|
||
|
|
for (var i = 0; i < bytes.Length; i++)
|
||
|
|
{
|
||
|
|
hexString += bytes[i].ToString("X2");
|
||
|
|
}
|
||
|
|
return hexString;
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// Determines if given string is in proper hexadecimal string format
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="hexString">string representing sequence of hex digits, no spaces</param>
|
||
|
|
/// <returns>true if all characters are hex digits, false otherwise</returns>
|
||
|
|
public static bool InHexFormat(string hexString)
|
||
|
|
{
|
||
|
|
var hexFormat = true;
|
||
|
|
|
||
|
|
foreach (var digit in hexString)
|
||
|
|
{
|
||
|
|
if (!IsHexDigit(digit))
|
||
|
|
{
|
||
|
|
hexFormat = false;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return hexFormat;
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// Returns true is c is a hexadecimal digit (A-F, a-f, 0-9)
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="c">Character to test</param>
|
||
|
|
/// <returns>true if hex digit, false if not</returns>
|
||
|
|
public static bool IsHexDigit(char c)
|
||
|
|
{
|
||
|
|
int numChar;
|
||
|
|
var numA = Convert.ToInt32('A');
|
||
|
|
var num1 = Convert.ToInt32('0');
|
||
|
|
c = char.ToUpper(c);
|
||
|
|
numChar = Convert.ToInt32(c);
|
||
|
|
if (numChar >= numA && numChar < (numA + 6))
|
||
|
|
return true;
|
||
|
|
if (numChar >= num1 && numChar < (num1 + 10))
|
||
|
|
return true;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// Converts 1 or 2 character string into equivalant byte value
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="hex">1 or 2 character string</param>
|
||
|
|
/// <returns>byte</returns>
|
||
|
|
private static byte HexToByte(string hex)
|
||
|
|
{
|
||
|
|
if (hex.Length > 2 || hex.Length <= 0)
|
||
|
|
throw new ArgumentException("hex must be 1 or 2 characters in length");
|
||
|
|
var newByte = byte.Parse(hex, System.Globalization.NumberStyles.HexNumber);
|
||
|
|
return newByte;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static string HexAsciiConvert(string hex)
|
||
|
|
{
|
||
|
|
var sb = new StringBuilder();
|
||
|
|
|
||
|
|
for (var i = 0; i < hex.Length; i += 2)
|
||
|
|
{
|
||
|
|
var hs = hex.Substring(i, 2);
|
||
|
|
var converted = Convert.ToUInt32(hs, 16);
|
||
|
|
if (converted == 0)
|
||
|
|
{
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
sb.Append(Convert.ToChar(converted));
|
||
|
|
}
|
||
|
|
|
||
|
|
return sb.ToString();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|