【问题标题】:Converting long string of binary to hex c#将长二进制字符串转换为十六进制c#
【发布时间】:2020-01-04 11:22:55
【问题描述】:

我正在寻找一种将长二进制字符串转换为十六进制字符串的方法。

二进制字符串看起来像这样"0110011010010111001001110101011100110100001101101000011001010110001101101011"

我尝试过使用

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

但这只有在二进制字符串适合 Uint64 时才有效,如果字符串足够长则不会。

还有其他方法可以将二进制字符串转换为十六进制吗?

谢谢

【问题讨论】:

  • 您为什么希望Convert.ToUInt64() 能够处理表示大于UInt64 可以容纳的值的字符串?

标签: c# binary hex


【解决方案1】:

我刚刚把它搞砸了。或许你可以以此为起点……

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

【讨论】:

  • 我认为 TODO 中的“否则”让我失望了。看到 TODO 的答案对我来说似乎很奇怪。你能解释一下吗?我不明白为什么这种方法需要在这些情况下抛出。此外,如果二进制为空,则会出现空引用,但这可能是您的意图。在这些情况下,我可能会添加一个警卫来返回 null。谢谢!
  • "看到 TODO 的答案对我来说似乎很奇怪:- 一点也不。我假设 OP 可以添加他们认为必要的守卫。我看不到他们的调用代码,也看不到我知道他们的全部用例意图。当然,空检查是谨慎的;我会添加一个...
【解决方案2】:

这可能会对您有所帮助:

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

【讨论】:

  • 该问题涉及超过 64 位的字符串。
  • 如果与大型二进制字符串一起使用将不起作用
【解决方案3】:
Convert.ToInt32("1011", 2).ToString("X");

对于比这个更长的字符串,你可以简单地把它分成多个字节:

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

【讨论】:

  • 你能解释一下什么是'2',第二个参数
  • '2' 告诉Convert.ToInt32 方法提供的字符串是基数2。考虑转换一个十六进制字符串"AABBCC" to int`(即11189196):只需指定您的字符串是基数16、像这样:Convert.ToInt32("AABBCC", 16)
  • 这个问题与包含超过 64 位数字的字符串有关,因此您的解决方案将无法正常工作
  • @Jesper,为答案添加了更多细节。感谢您指出这一点。
【解决方案4】:

我想出了这个方法。我是编程和 C# 的新手,但我希望你会喜欢它:

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

【讨论】:

    【解决方案5】:

    考虑到四个位可以用一个十六进制值表示,您可以简单地以四个为一组,分别转换,值不会那样改变。

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

    【讨论】:

      【解决方案6】:

      如果您想遍历字符串中每个字节的十六进制表示,您可以使用以下扩展名。我已将 Mitch 的回答与 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));
              }
          }
      }
      

      例子:

      string test = "0110011010010111001001110101011100110100001101101000011001010110001101101011";
      
      foreach (var hexVal in test.ToHex())
      {
          Console.WriteLine(hexVal);  
      }
      

      打印

      06
      69
      72
      75
      73
      43
      68
      65
      63
      6B
      

      【讨论】:

        【解决方案7】:

        如果您使用 .NET 4.0 或更高版本并且愿意使用 System.Numerics.dll(用于 BigInteger 类),则以下解决方案可以正常工作:

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

        【讨论】:

          【解决方案8】:

          考虑到四个位可以用一个十六进制值表示,您可以简单地以四个为一组,分别转换,值不会那样改变。

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

          【讨论】:

            【解决方案9】:
            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);
            }
            

            【讨论】:

              【解决方案10】:

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

              【讨论】:

                【解决方案11】:

                您可以一次输入四位数字。将此数字转换为 ex (正如您所做的那样),然后将字符串连接在一起。因此,您获得了一个表示十六进制数字的字符串,与大小无关。根据您输入字符串的起始 MSB 位置,可能是您获得的输出字符串,我描述的方式必须是 reversed

                【讨论】:

                  猜你喜欢
                  • 2016-06-02
                  • 2017-02-23
                  • 2014-08-03
                  • 1970-01-01
                  • 2018-01-31
                  • 1970-01-01
                  • 2019-08-23
                  • 1970-01-01
                  相关资源
                  最近更新 更多