【问题标题】:how can i convert array of eight numbers '0' and '1' characters to byte in c#如何在c#中将八个数字'0'和'1'字符的数组转换为字节
【发布时间】:2020-09-26 07:58:04
【问题描述】:

我有一个字符数组,包括 '0' 和 '1' 如何在 c# 中将其转换为字节数据类型?

char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};

【问题讨论】:

  • 您的意思是将 8 个10 转换为一个字节吗?如果是这样;问题的结束还为时过早,edit 问题更明确。如果你这样做,它可能会重新打开。

标签: c#


【解决方案1】:

您也可以使用Convert 来做到这一点

char[] chars = new char[] { '0', '1', '1', '0', '0', '0', '1', '1' };

string binaryString = string.Join(string.Empty, chars);
byte result = Convert.ToByte(binaryString, 2);

【讨论】:

    【解决方案2】:

    让我们开始吧,

    我们做一个循环,检查我们是否有'1',如果有,我们想把那个位添加到结果中……

    char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};
    
    byte result = 0;
    byte current = 1;
    for (var index = 0; index < chars.Length; index++)
    {
        if (chars[index] == '1')
        {
            result += current;
        }
    
        current *= 2;
    }
    
    Console.WriteLine(result); // 198
    

    让我们检查…198 二进制是…11000110。啊,你看,我假设第一个索引是最不有价值的位,因此我把它反过来了。所以,让我们翻转它。

    顺便说一句,我将result 声明为byte,这也预设了数组最多有8 个项目。对于以下代码,我假设数组正好有 8 个项目。

    char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};
    
    byte result = 0;
    byte current = 1;
    for (var index = 0; index < chars.Length; index++)
    {
        if (chars[index] == '1')
        {
            result += current;
        }
    
        current *= 2;
    }
    
    Console.WriteLine(result); // 99
    

    检查,99 是二进制的1100011。让我们把这个假设编成代码,好吗?

    char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};
    
    if (chars.Length != 8)
    {
        throw new ArgumentOutOfRangeException();
    }
    
    byte result = 0;
    byte current = 128;
    for (var index = 0; index < 8; index++)
    {
        if (chars[index] == '1')
        {
            result += current;
        }
    
        current /= 2;
    }
    
    Console.WriteLine(result);
    

    好的,我们现在可以反转循环以进行微优化。

    char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};
    
    if (chars.Length != 8)
    {
        throw new ArgumentOutOfRangeException();
    }
    
    byte result = 0;
    byte current = 1;
    for (var index = 7; index >= 0; index--)
    {
        if (chars[index] == '1')
        {
            result += current;
        }
    
        current *= 2;
    }
    
    Console.WriteLine(result);
    

    让我们进行二进制移位而不是乘以 2。

    char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};
    
    if (chars.Length != 8)
    {
        throw new ArgumentOutOfRangeException();
    }
    
    byte result = 0;
    byte current = 1;
    for (var index = 7; index >= 0; index--)
    {
        if (chars[index] == '1')
        {
            result += current;
        }
    
        current <<= 1;
    }
    
    Console.WriteLine(result);
    

    让我们再加一个假设:数组只有'0''1'

    char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};
    
    if (chars.Length != 8)
    {
        throw new ArgumentOutOfRangeException();
    }
    
    for (var index = 7; index >= 0; index--)
    {
        if (chars[index] != '0' && chars[index] != '1')
        {
            throw new ArgumentOutOfRangeException();
        }
    }
    
    byte result = 0;
    byte current = 1;
    for (var index = 7; index >= 0; index--)
    {
        if (chars[index] == '1')
        {
            result += current;
        }
    
        current <<= 1;
    }
    
    Console.WriteLine(result);
    

    当然,如果您可以通过其他方式保证,您可以删除验证。我假设你会这样做。

    接下来,让我们注意,当我们将char 转换为int(这是一个安全的转换)时,'0' 将是48 并且'1' 将是49。这些值仅在最后一位(最低值)有所不同,而该位就是我们想要的值。

    知道了,我可以直接设置位:

    char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};
    
    byte result = 0;
    byte current = 1;
    for (var index = 7; index >= 0; index--)
    {
        result |= unchecked((byte)(current * (chars[index] & 1)));
        current <<= 1;
    }
    
    Console.WriteLine(result);
    

    在上面的代码中,我使用二进制掩码 &amp; 1 从字符代码(4849)中提取 01。然后乘以current。因此,如果找到1,我们设置当前位,如果找到0,则不设置。

    嗯,我们可以直接shift,给我们保存一个变量。

    char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};
    
    byte result = 0;
    for (var index = 7; index >= 0; index--)
    {
        result |= unchecked((byte)((1 << (7 - index)) * (chars[index] & 1)));
    }
    
    Console.WriteLine(result);
    

    在上面的代码中,我没有保留current,而是在每次迭代时计算它。

    我们可以在没有乘法的情况下做到这一点。我们改用01

    char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};
    
    byte result = 0;
    for (var index = 7; index >= 0; index--)
    {
        result |= unchecked((byte)(((chars[index] & 1) << (7 - index))));
    }
    
    Console.WriteLine(result);
    

    在上面,我转移了来自字符代码的01。为我们节省了一个乘法。

    让我们展开 for,我们知道总是有 8 次迭代。

    char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};
    
    byte result = 0;
    
    result |= unchecked((byte)(((chars[7] & 1) << (7 - 7))));
    result |= unchecked((byte)(((chars[6] & 1) << (7 - 6))));
    result |= unchecked((byte)(((chars[5] & 1) << (7 - 5))));
    result |= unchecked((byte)(((chars[4] & 1) << (7 - 4))));
    result |= unchecked((byte)(((chars[3] & 1) << (7 - 3))));
    result |= unchecked((byte)(((chars[2] & 1) << (7 - 2))));
    result |= unchecked((byte)(((chars[1] & 1) << (7 - 1))));
    result |= unchecked((byte)(((chars[0] & 1) << (7 - 0))));
    
    Console.WriteLine(result);
    

    我们可以稍微简化一下:

    char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};
    
    byte result = 0;
    
    result |= unchecked((byte)(((chars[7] & 1) << 0)));
    result |= unchecked((byte)(((chars[6] & 1) << 1)));
    result |= unchecked((byte)(((chars[5] & 1) << 2)));
    result |= unchecked((byte)(((chars[4] & 1) << 3)));
    result |= unchecked((byte)(((chars[3] & 1) << 4)));
    result |= unchecked((byte)(((chars[2] & 1) << 5)));
    result |= unchecked((byte)(((chars[1] & 1) << 6)));
    result |= unchecked((byte)(((chars[0] & 1) << 7)));
    
    Console.WriteLine(result);
    

    我们如何在一次操作中执行此操作并在最后转换为byte

    char[] chars = new char[] {'0', '1', '1', '0', '0', '0' , '1', '1'};
    
    byte result = unchecked((byte)(
        ((chars[7] & 1) << 0)
        | ((chars[6] & 1) << 1)
        | ((chars[5] & 1) << 2)
        | ((chars[4] & 1) << 3)
        | ((chars[3] & 1) << 4)
        | ((chars[2] & 1) << 5)
        | ((chars[1] & 1) << 6)
        | ((chars[0] & 1) << 7)
    ));
    
    Console.WriteLine(result);
    

    太棒了!因此,我们从字符代码中提取01(使用掩码),并将其移动到字节中的位置,将它们放在一起,我们就得到了结果。希望它的工作原理和我们如何到达那里都有意义。

    【讨论】:

      【解决方案3】:

      你可以使用位操作符:

      char[] chars = new char[] {'1', '1', '1', '0', '0', '0' , '1', '1'};
      byte theResult=0;
      foreach(char ch in chars)
      {
          byte bit=byte.Parse(ch.ToString());
          theResult=(byte)(theResult<<1);
          theResult+=bit;
      }
      

      这里https://rextester.com/FXQOJ83728你可以测试我的代码。

      【讨论】:

        【解决方案4】:

        如果我们可以假设如果输入数组中的一个char不是'0',则将其视为'1',则可以使用Linq计算字节如下:

        byte b = chars
            .Select((c, i) => (byte)(c == '0' ? 0 : 1 << (7-i))) // Convert each char to a power of 2.
            .Aggregate((byte)0, (b1, b2) => (byte)(b1 | b2));    // OR all the converted values together.
        

        请注意,移位是 &lt;&lt;(7-i) 而不仅仅是 &lt;&lt; i,因为 MSB(最高有效位)在前。

        Try it on DotNetFiddle

        说实话,我不会为此使用 Linq。我会这样做:

        byte b = 0;
        
        for (int i = 0; i < 8; ++i)
            if (chars[i] != '0')
                b |= (byte)(1 << 7 - i);
        

        Try it on DotNetFiddle

        【讨论】:

          【解决方案5】:

          使用这个:

          var bytes = Encoding.ASCII.GetBytes(chars);
          

          【讨论】:

          • 这个答案不正确。它提取 0 和 1 个字符的 ascii 代码。
          猜你喜欢
          • 2010-09-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-09-22
          • 1970-01-01
          • 1970-01-01
          • 2017-05-07
          相关资源
          最近更新 更多