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

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
Midimatt
  • 1,114
  • 2
  • 17
  • 35
  • 9
    Why would you expect `Convert.ToUInt64()` to be able to handle a string that represents a value larger than a `UInt64` can hold? – Andrew Barber Apr 10 '11 at 14:14

11 Answers11

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();
}
Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
  • 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! – masterwok Aug 26 '19 at 11:24
  • 1
    "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... – Mitch Wheat Aug 27 '19 at 04:59
11

This might help you:

string HexConverted(string strBinary)
    {
        string strHex = Convert.ToInt32(strBinary,2).ToString("X");
        return strHex;
    }
Aswin Murugesh
  • 10,831
  • 10
  • 40
  • 69
Pranav Labhe
  • 1,943
  • 1
  • 19
  • 24
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")));
Soroush Falahati
  • 2,196
  • 1
  • 27
  • 38
  • can you please explain what is '2' , the second parameter – Fazal Apr 30 '16 at 06:48
  • 1
    '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)` – Alex McMillan Jul 01 '16 at 03:01
  • The question is concerned with strings containing numbers longer that 64bit so your solution won't work – Jesper Nov 15 '18 at 10:13
  • @Jesper, added more detail to the answer. Thanks for pointing this out. – Soroush Falahati Nov 16 '18 at 10:37
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();
}
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
Community
  • 1
  • 1
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");
}
Marcos Arruda
  • 532
  • 7
  • 15
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));
}
Femaref
  • 60,705
  • 7
  • 138
  • 176
0

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));
}
Femaref
  • 60,705
  • 7
  • 138
  • 176
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);
}
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
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();

            }
Kingeh
  • 29
  • 4
-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.

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115