开发者

C# how convert large HEX string to binary

I have a string with 14 characters . This is a hex represantation of 7bytes. I want to convert it to binary. I tried using Convert.ToString(Convert.ToInt32(hexstring, 16), 2); For small strings this works but for 14 characters it will not work becaus开发者_如何学Pythone the result is too large. How can i manage this? Keep in mind that the output of the conversion should be a binary string with a lengeth of 56 characters (we must keep the leading zeros). (e.g. conversion of (byte)0x01 should yield "00000001" rather than "1")


You can just convert each hexadecimal digit into four binary digits:

string binarystring = String.Join(String.Empty,
  hexstring.Select(
    c => Convert.ToString(Convert.ToInt32(c.ToString(), 16), 2).PadLeft(4, '0')
  )
);

You need a using System.Linq; a the top of the file for this to work.


Convert.ToString(Convert.ToInt64(hexstring, 16), 2);

Maybe? Or

Convert.ToString(Convert.ToInt64(hexstring, 16), 2).PadLeft(56, '0');


Why not just take the simple approach and define your own mapping?

private static readonly Dictionary<char, string> hexCharacterToBinary = new Dictionary<char, string> {
    { '0', "0000" },
    { '1', "0001" },
    { '2', "0010" },
    { '3', "0011" },
    { '4', "0100" },
    { '5', "0101" },
    { '6', "0110" },
    { '7', "0111" },
    { '8', "1000" },
    { '9', "1001" },
    { 'a', "1010" },
    { 'b', "1011" },
    { 'c', "1100" },
    { 'd', "1101" },
    { 'e', "1110" },
    { 'f', "1111" }
};

public string HexStringToBinary(string hex) {
    StringBuilder result = new StringBuilder();
    foreach (char c in hex) {
        // This will crash for non-hex characters. You might want to handle that differently.
        result.Append(hexCharacterToBinary[char.ToLower(c)]);
    }
    return result.ToString();
}

Note that this will keep leading zeros. So "aa" would be converted to "10101010" while "00000aa" would be converted to "0000000000000000000010101010".


You can get a byte array from hex string using this code

 public static byte[] StringToByteArray(String hex)
    {
        int NumberChars = hex.Length;
        byte[] bytes = new byte[NumberChars / 2];
        for (int i = 0; i < NumberChars; i += 2)
            bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
        return bytes;
    }


My C++ background answer:

private Byte[] HexToBin(string pHexString)
{
    if (String.IsNullOrEmpty(pHexString))
        return new Byte[0];

    if (pHexString.Length % 2 != 0)
        throw new Exception("Hexstring must have an even length");

    Byte[] bin = new Byte[pHexString.Length / 2];
    int o = 0;
    int i = 0;
    for (; i < pHexString.Length; i += 2, o++)
    {
        switch (pHexString[i])
        {
            case '0': bin[o] = 0x00; break;
            case '1': bin[o] = 0x10; break;
            case '2': bin[o] = 0x20; break;
            case '3': bin[o] = 0x30; break;
            case '4': bin[o] = 0x40; break;
            case '5': bin[o] = 0x50; break;
            case '6': bin[o] = 0x60; break;
            case '7': bin[o] = 0x70; break;
            case '8': bin[o] = 0x80; break;
            case '9': bin[o] = 0x90; break;
            case 'A':
            case 'a': bin[o] = 0xa0; break;
            case 'B':
            case 'b': bin[o] = 0xb0; break;
            case 'C':
            case 'c': bin[o] = 0xc0; break;
            case 'D':
            case 'd': bin[o] = 0xd0; break;
            case 'E':
            case 'e': bin[o] = 0xe0; break;
            case 'F':
            case 'f': bin[o] = 0xf0; break;
            default: throw new Exception("Invalid character found during hex decode");
        }

        switch (pHexString[i+1])
        {
            case '0': bin[o] |= 0x00; break;
            case '1': bin[o] |= 0x01; break;
            case '2': bin[o] |= 0x02; break;
            case '3': bin[o] |= 0x03; break;
            case '4': bin[o] |= 0x04; break;
            case '5': bin[o] |= 0x05; break;
            case '6': bin[o] |= 0x06; break;
            case '7': bin[o] |= 0x07; break;
            case '8': bin[o] |= 0x08; break;
            case '9': bin[o] |= 0x09; break;
            case 'A':
            case 'a': bin[o] |= 0x0a; break;
            case 'B':
            case 'b': bin[o] |= 0x0b; break;
            case 'C':
            case 'c': bin[o] |= 0x0c; break;
            case 'D':
            case 'd': bin[o] |= 0x0d; break;
            case 'E':
            case 'e': bin[o] |= 0x0e; break;
            case 'F':
            case 'f': bin[o] |= 0x0f; break;
            default: throw new Exception("Invalid character found during hex decode");
        }
    }
    return bin;
}


You can do this.

I have put it in a class called UtilMath this is a good Idea as, if you ever use it in a different program you can use the class again. And as the name implies this is for all my Math functions.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Math.Util
{
    class UtilMath
    {

        public static string hex2binary(string hexvalue)
        {
            // Convert.ToUInt32 this is an unsigned int
            // so no negative numbers but it gives you one more bit
            // it much of a muchness 
            // Uint MAX is 4,294,967,295 and MIN is 0
            // this padds to 4 bits so 0x5 = "0101"
            return String.Join(String.Empty, hexvalue.Select(c => Convert.ToString(Convert.ToUInt32(c.ToString(), 16), 2).PadLeft(4, '0')));
        }
    }
}

now before you use it you need to include it,

using Math.Util

then if you need to use it you can call it by going

UtilMath.hex2binary("FF");

Or

String hexString = "FF";
UtilMath.hex2binary(hexString);

Hope this helps.


Convert.FromHexString has been introduced in .Net 5

 var bytes = Convert.FromHexString("13AF3F")


What if you convert one character at a time? I'm can't test this out, but the idea should work.

//Convert.ToString(Convert.ToInt32(hexstring, 16), 2)

StringBuilder sb = new StringBuilder();
foreach( char c in hexstring.ToCharArray() ){
  sb.Append( Convert.ToString(Convert.ToInt32(c.ToString(), 16), 2);
}


How about using Int64 instead of Int32?

Convert.ToString(Convert.ToInt64(hexstring, 16), 2);


If you need a byte array, you can get it by:

Collection<byte> bytes = new Collection<byte>();
for (int i = 0; i < hexText.Length; i += 2) {
    byte bin = BitConverter.GetBytes(Convert.ToInt32(hexText.Substring(i, 2), 16))[0];
    bytes.Add(bin);
}

But if it is directly to save to a file, I would do it directly:

using FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.Write);
for (int i = 0; i < hexText.Length; i += 2) {
    byte bin = BitConverter.GetBytes(Convert.ToInt32(hexText.Substring(i, 2), 16))[0];
    fileStream.WriteByte(bin);
}
fileStream.Close();
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜