How to convert hex to a byte array?

匿名 (未验证) 提交于 2019-12-03 09:02:45

问题:

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#?

回答1:

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.



回答2:

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); 


回答3:

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.



回答4:

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 


回答5:

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 


回答6:

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



回答7:

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();     } 


回答8:

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 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!