18

I'm looking for a way to convert a long string of binary to a hex string.

the binary string looks something like this "0110011010010111001001110101011100110100001101101000011001010110001101101011"

I've tried using

hex = String.Format("{0:X2}", Convert.ToUInt64(hex, 2));

but that only works if the binary string fits into a Uint64 which if the string is long enough it won't.

is there another way to convert a string of binary into hex?

Thanks

1
  • 9
    Why would you expect Convert.ToUInt64() to be able to handle a string that represents a value larger than a UInt64 can hold? Commented Apr 10, 2011 at 14:14

11 Answers 11

36

I just knocked this up. Maybe you can use as a starting point...

public static string BinaryStringToHexString(string binary)
{
    if (string.IsNullOrEmpty(binary))
        return binary;

    StringBuilder result = new StringBuilder(binary.Length / 8 + 1);

    // TODO: check all 1's or 0's... throw otherwise

    int mod4Len = binary.Length % 8;
    if (mod4Len != 0)
    {
        // pad to length multiple of 8
        binary = binary.PadLeft(((binary.Length / 8) + 1) * 8, '0');
    }

    for (int i = 0; i < binary.Length; i += 8)
    {
        string eightBits = binary.Substring(i, 8);
        result.AppendFormat("{0:X2}", Convert.ToByte(eightBits, 2));
    }

    return result.ToString();
}
Sign up to request clarification or add additional context in comments.

2 Comments

I think the "throw otherwise" in the TODO was throwing me off. Seeing an answer with a TODO seems odd to me. Could you explain that please? I dont understand why this method would ever need to throw in those cases. Also, a null reference will occur if binary is null but maybe that was your intent. I would of probably added a guard to return null in those cases. Thank you!
"Seeing an answer with a TODO seems odd to me: - not at all. I'm assuming the OP can add as many guards they deem necessary. I can't see their calling code nor do I know their full use case intent. A null check would be prudent of course; I will add one...
11

This might help you:

string HexConverted(string strBinary)
    {
        string strHex = Convert.ToInt32(strBinary,2).ToString("X");
        return strHex;
    }

2 Comments

The question is concerned with strings of more than 64 bits.
Will not work if used with large binary strings
6
Convert.ToInt32("1011", 2).ToString("X");

For string longer than this, you can simply break it into multiple bytes:

var binary = "0110011010010111001001110101011100110100001101101000011001010110001101101011";
var hex = string.Join(" ", 
            Enumerable.Range(0, binary.Length / 8)
            .Select(i => Convert.ToByte(binary.Substring(i * 8, 8), 2).ToString("X2")));

4 Comments

can you please explain what is '2' , the second parameter
'2' tells the Convert.ToInt32 method that the string provided is base 2. Consider converting a hex string "AABBCC" to int` (which is 11189196): simply specify your string is in base 16, like this: Convert.ToInt32("AABBCC", 16)
The question is concerned with strings containing numbers longer that 64bit so your solution won't work
@Jesper, added more detail to the answer. Thanks for pointing this out.
4

I came up with this method. I am new to programming and C# but I hope you will appreciate it:

static string BinToHex(string bin)
{
    StringBuilder binary = new StringBuilder(bin);
    bool isNegative = false;
    if (binary[0] == '-')
    {
        isNegative = true;
        binary.Remove(0, 1);
    }

    for (int i = 0, length = binary.Length; i < (4 - length % 4) % 4; i++) //padding leading zeros
    {
        binary.Insert(0, '0');
    }

    StringBuilder hexadecimal = new StringBuilder();
    StringBuilder word = new StringBuilder("0000");
    for (int i = 0; i < binary.Length; i += 4)
    {
        for (int j = i; j < i + 4; j++)
        {
            word[j % 4] = binary[j];
        }

        switch (word.ToString())
        {
            case "0000": hexadecimal.Append('0'); break;
            case "0001": hexadecimal.Append('1'); break;
            case "0010": hexadecimal.Append('2'); break;
            case "0011": hexadecimal.Append('3'); break;
            case "0100": hexadecimal.Append('4'); break;
            case "0101": hexadecimal.Append('5'); break;
            case "0110": hexadecimal.Append('6'); break;
            case "0111": hexadecimal.Append('7'); break;
            case "1000": hexadecimal.Append('8'); break;
            case "1001": hexadecimal.Append('9'); break;
            case "1010": hexadecimal.Append('A'); break;
            case "1011": hexadecimal.Append('B'); break;
            case "1100": hexadecimal.Append('C'); break;
            case "1101": hexadecimal.Append('D'); break;
            case "1110": hexadecimal.Append('E'); break;
            case "1111": hexadecimal.Append('F'); break;
            default:
                return "Invalid number";
        }
    }

    if (isNegative)
    {
        hexadecimal.Insert(0, '-');
    }

    return hexadecimal.ToString();
}

Comments

1

Considering four bits can be expressed by one hex value, you can simply go by groups of four and convert them seperately, the value won't change that way.

string bin = "11110110";

int rest = bin.Length % 4;
bin = bin.PadLeft(rest, '0'); //pad the length out to by divideable by 4

string output = "";

for(int i = 0; i <= bin.Length - 4; i +=4)
{
    output += string.Format("{0:X}", Convert.ToByte(bin.Substring(i, 4), 2));
}

Comments

1

Considering four bits can be expressed by one hex value, you can simply go by groups of four and convert them seperately, the value won't change that way.

string bin = "11110110";

int rest = bin.Length % 4;
if(rest != 0)
    bin = new string('0', 4-rest) + bin; //pad the length out to by divideable by 4

string output = "";

for(int i = 0; i <= bin.Length - 4; i +=4)
{
    output += string.Format("{0:X}", Convert.ToByte(bin.Substring(i, 4), 2));
}

Comments

1

If you want to iterate over the hexadecimal representation of each byte in the string, you could use the following extension. I've combined Mitch's answer with this.

static class StringExtensions
{
    public static IEnumerable<string> ToHex(this String s) {
        if (s == null)
            throw new ArgumentNullException("s");

        int mod4Len = s.Length % 8;
        if (mod4Len != 0)
        {
            // pad to length multiple of 8
            s = s.PadLeft(((s.Length / 8) + 1) * 8, '0');
        }

        int numBitsInByte = 8;
        for (var i = 0; i < s.Length; i += numBitsInByte)
        {
            string eightBits = s.Substring(i, numBitsInByte);
            yield return string.Format("{0:X2}", Convert.ToByte(eightBits, 2));
        }
    }
}

Example:

string test = "0110011010010111001001110101011100110100001101101000011001010110001101101011";

foreach (var hexVal in test.ToHex())
{
    Console.WriteLine(hexVal);  
}

Prints

06
69
72
75
73
43
68
65
63
6B

Comments

1

If you're using .NET 4.0 or later and if you're willing to use System.Numerics.dll (for BigInteger class), the following solution works fine:

public static string ConvertBigBinaryToHex(string bigBinary)
{
    BigInteger bigInt = BigInteger.Zero;
    int exponent = 0;

    for (int i = bigBinary.Length - 1; i >= 0; i--, exponent++)
    {
        if (bigBinary[i] == '1')
            bigInt += BigInteger.Pow(2, exponent);
    }

    return bigInt.ToString("X");
}

Comments

0
static string BinToHex(string bin)
{
    if (bin == null)
        throw new ArgumentNullException("bin");
    if (bin.Length % 8 != 0)
        throw new ArgumentException("The length must be a multiple of 8", "bin");

    var hex = Enumerable.Range(0, bin.Length / 8)
                     .Select(i => bin.Substring(8 * i, 8))
                     .Select(s => Convert.ToByte(s, 2))
                     .Select(b => b.ToString("x2"));
    return String.Join(null, hex);
}

Comments

0

Using LINQ

   string BinaryToHex(string binaryString)
            {
                var offset = 0;
                StringBuilder sb = new();
                
                while (offset < binaryString.Length)
                {
                    var nibble = binaryString
                        .Skip(offset)
                        .Take(4);

                    sb.Append($"{Convert.ToUInt32(nibble.toString()), 2):X}");
                    offset += 4;
                }

                return sb.ToString();

            }

Comments

-1

You can take the input number four digit at a time. Convert this digit to ex ( as you did is ok ) then concat the string all together. So you obtain a string representing the number in hex, independetly from the size. Depending on where start MSB on your input string, may be the output string you obtain the way i described must be reversed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.