I copied and pasted this binary data out of sql server, which I am unable to query at this time.
0xBAC893CAB8B7FE03C927417A2A3F6A60BD30FF35E250011CB25507EBFCD5223B
How do I convert it back to a byte array in c#?
I copied and pasted this binary data out of sql server, which I am unable to query at this time.
0xBAC893CAB8B7FE03C927417A2A3F6A60BD30FF35E250011CB25507EBFCD5223B
How do I convert it back to a byte array in c#?
Something like this:
using System; public static class Parser { static void Main() { string hex = "0xBAC893CAB8B7FE03C927417A2A3F6A6" + "0BD30FF35E250011CB25507EBFCD5223B"; byte[] parsed = ParseHex(hex); // Just for confirmation... Console.WriteLine(BitConverter.ToString(parsed)); } public static byte[] ParseHex(string hex) { int offset = hex.StartsWith("0x") ? 2 : 0; if ((hex.Length % 2) != 0) { throw new ArgumentException("Invalid length: " + hex.Length); } byte[] ret = new byte[(hex.Length-offset)/2]; for (int i=0; i = '0' && c = 'A' && c = 'a' && c
(EDIT: Now slightly more efficient - no substrings required...)
It's possible that ParseNybble
could be more efficient. For example, a switch/case may be more efficient:
static int ParseNybble(char c) { switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': return c-'0'; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': return c-'A'+10; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': return c-'a'+10; } throw new ArgumentException("Invalid hex digit: " + c); }
or possibly a lookup array:
// Omitted for brevity... I'm sure you get the gist private static readonly int[] NybbleLookup = BuildLookup(); private int ParseNybble(char c) { if (c > 'f') { throw new ArgumentException("Invalid hex digit: " + c); } int ret = NybbleLookup[c]; if (ret == -1) { throw new ArgumentException("Invalid hex digit: " + c); } return ret; }
I haven't benchmarked any of these, and I've no idea which would be the fastest. The current solution is probably the simplest though.
Consider leveraging a Framework class that already exposes the ability to perform hex conversion, XmlReader for example:
public static byte[] HexToBytes(this string hexEncodedBytes, int start, int end) { int length = end - start; const string tagName = "hex"; string fakeXmlDocument = String.Format("{0}{1}>", hexEncodedBytes.Substring(start, length), tagName); var stream = new MemoryStream(Encoding.ASCII.GetBytes(fakeXmlDocument)); XmlReader reader = XmlReader.Create(stream, new XmlReaderSettings()); int hexLength = length / 2; byte[] result = new byte[hexLength]; reader.ReadStartElement(tagName); reader.ReadContentAsBinHex(result, 0, hexLength); return result; }
usage:
string input = "0xBAC893CAB8B7FE03C927417A2A3F6A60BD30FF35E250011CB255"; byte[] bytes = input.HexToBytes(2, input.Length);
Simple:
string hexnum = "0000000F"; // Represents 15 int value = int.Parse(hexnum, System.Globalization.NumberStyles.HexNumber);
All you have to remember to do is for an int to divide the hex number up into groups of 8 hex digits (hex are 4 bits each, and CLR int type is 32 bits, hence 8 digits per int). There's also a byte.Parse() that works the same, but pass in two hex digits at a time.
Something like this:
public byte[] ParseHexString(string text) { if ((text.Length % 2) != 0) { throw new ArgumentException("Invalid length: " + text.Length); } if (text.StartsWith("0x", StringComparison.InvariantCultureIgnoreCase)) { text = text.Substring(2); } int arrayLength = text.Length / 2; byte[] byteArray = new byte[arrayLength]; for (int i = 0; i
You will need to modify this a little bit (for example, skip over the first two characters), but it does handle spaces in the string:
/// /// Decodes a hex string, ignoring all non-hex characters, and stores /// the decodes series of bytes into the shared buffer. This returns /// the number of bytes that were decoded. /// Hex characters are [0-9, a-f, A-F]. /// /// String to parse into bytes. /// Buffer into which to store the decoded binary data. /// The number of bytes decoded. private static int DecodeHexIntoBuffer(string hexString, byte[] buffer) { int count = 0; bool haveFirst = false; bool haveSecond = false; char first = '0'; char second = '0'; for (int i = 0; i
Slow yet fun way :D
public static byte[] StringToByteArray(string hex) { hex = hex.Replace(" ", ""); hex = hex.Replace(":", ""); return Enumerable.Range(0, hex.Length) .Where(x => x % 2 == 0) .Select(x => Convert.ToByte(hex.Substring(x, 2), 16)) .ToArray(); }
-jD
Actually, there's an easier way to convert two characters at a time to a byte:
/// /// This will convert a hex-encoded string to byte data /// /// The hex-encoded string to convert /// The bytes that make up the hex string public static byte[] FromHex(string hexData) { List data = new List(); string byteSet = string.Empty; int stringLen = hexData.Length; int length = 0; for (int i = 0; i 1 ? 2 : 1; byteSet = hexData.Substring(i, length); // try and parse the data data.Add(Convert.ToByte(byteSet, 16 /*base*/)); } // next set return data.ToArray(); }
I use this for C#, from similar code in Java.
private static char[] hexdigit = "0123456789abcdef".ToCharArray(); public static string hexlify(string argbuf) { int arglen = argbuf.Length; char[] argca = argbuf.ToCharArray (); StringBuilder retbuf = new StringBuilder(arglen * 2); for (int i = 0; i > 4) & 0xF]); retbuf.Append(hexdigit[ch & 0xF]); } return retbuf.ToString(); } public static string unhexlify(string argbuf) { int arglen = argbuf.Length; if (arglen % 2 != 0) { throw new ArgumentOutOfRangeException ("Odd-length string"); } char[] argca = argbuf.ToCharArray (); StringBuilder retbuf = new StringBuilder(arglen / 2); for (int i = 0; i