using System; using System.Text; namespace DTS.Common.Utilities { /// /// Summary description for HexEncoding. /// /// 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 /// public static class HexEncoding { /// /// returns the number of bytes needed to represent hex string /// /// hex string to calculate /// number of bytes /// doesn't count non hex characters /// odd number of characters, last character is discarded /// 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 } /// /// 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. /// /// string to convert to byte array /// number of characters in string ignored /// byte array, in the same left-to-right order as the hexString 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; } /// /// returns a string representation out of byte array /// /// an array of hex characters packed 2 per byte /// string representation of hex characters in byte array, no spaces between bytes public static string ToString(byte[] bytes) { var hexString = ""; for (var i = 0; i < bytes.Length; i++) { hexString += bytes[i].ToString("X2"); } return hexString; } /// /// Determines if given string is in proper hexadecimal string format /// /// string representing sequence of hex digits, no spaces /// true if all characters are hex digits, false otherwise public static bool InHexFormat(string hexString) { var hexFormat = true; foreach (var digit in hexString) { if (!IsHexDigit(digit)) { hexFormat = false; break; } } return hexFormat; } /// /// Returns true is c is a hexadecimal digit (A-F, a-f, 0-9) /// /// Character to test /// true if hex digit, false if not 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; } /// /// Converts 1 or 2 character string into equivalant byte value /// /// 1 or 2 character string /// byte 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(); } } }