【问题标题】:How to fill a BitArray so that copying it to a byte will work如何填充 BitArray 以便将其复制到字节中
【发布时间】:2012-06-04 03:34:12
【问题描述】:

请考虑将斜线符号(例如 24、30)转换为子网掩码的这个(非家庭作业)练习。

当我将BitArray 复制到byte[] 时,BitArray 的内部排序会导致输出不正确。

例如,输入numberOfSetBits=24,ToString() 应该返回255.255.255.0(这是因为位是对称的)。 但是,30 的输入会导致255.255.255.63 而不是预期的255.255.255.252。 是的,我知道that's just the way a BitArray handles it's children(有一个关于这个问题的old discussion,很遗憾没有解决方案,只是关于为什么一个订购会更好的永无止境的争论)。

但是,看在上帝的份上,我怎样才能得到这段代码来处理 1111 1100 (=252) 的本来面目,而不是将其修改为 0011 1111 (=63)?我相信我必须首先更改添加位的顺序,但我无法让它工作。

public class SubnetMask
{
    private byte[] parts = new byte[4];

    public static SubnetMask FromSlash(int numberOfSetBits)
    {
        BitArray bits = new BitArray(32);
        for (int i = 0; i < numberOfSetBits; i++)
        {
            bits[i] = true;
        }
        return new SubnetMask(bits);
    }

    private SubnetMask(BitArray bits)
    {
        bits.CopyTo(parts, 0);
    }

    public override string ToString()
    {
        return string.Join(".", parts);
    }
}

谢谢。

【问题讨论】:

  • @Mehrdad 不错的一个 - 记下另一个我不知道存在的课程 :-)
  • @ChrisShain:哈哈。我想你的意思是struct。 :P

标签: c# bit-manipulation bitarray


【解决方案1】:

您不需要BitArray,您可以通过移动整数来创建掩码,然后使用BitConverter.GetBytes 将其作为字节获取:

public static SubnetMask FromSlash(int numberOfSetBits) {
  int mask = numberOfSetBits == 0 ? 0 : -1 << (32 - numberOfSetBits);
  byte[] bits = BitConverter.GetBytes(mask);
  if (BitConverter.IsLittleEndian) Array.Reverse(bits);
  return new SubnetMask(bits);
}

【讨论】:

  • 有趣的是,它不适用于输入 0。任何解释为什么将整数左移 32 位会使我得到原始整数?
  • @codesparkle: 啊......移位只使用了第二个操作数的五位,即x &lt;&lt; (y &amp; 0x1f)。 “计数被屏蔽为 5 位”:jsimlo.sk/docs/cpu/index.php/shl.html 所以您需要对此进行额外检查。
  • 这很烦人.. 我想知道为什么必须这样限制它。您能否更新您的答案以反映这一点?例如numberOfSetBits == 0 ? 0 : -1 &lt;&lt; (32 - numberOfSetBits)
【解决方案2】:

这不是通过以下方式解决的吗:

int bitPlace = 32;
for (int i = 0; i < numberOfSetBits; i++)
{
    bits[--bitPlace] = true;
}

这会设置高位(而不是低位)。这里的推理正是您链接的答案中提到的 - BitArray 将最低有效数字存储在最低索引中,因此下面的位数组 11111000000000 是 [indexed] 因此:

(Most Significant)                  (Least Significant)
 1    1    1    1    1   0   0   0   0   0   0   0   0   0
[14] [13] [11] [10] [9] [8] [7] [6] [5] [4] [3] [2] [1] [0]

【讨论】:

  • 这确实有效,但是它需要在 SubnetMask 构造函数中进行此更改:parts = parts.Reverse().ToArray(); 以修复字节的顺序。
  • 感谢您的努力 - 我投了赞成票,但我只能设置一个帖子作为答案。
猜你喜欢
  • 1970-01-01
  • 2010-09-29
  • 2016-12-09
  • 2018-05-09
  • 1970-01-01
  • 2023-03-06
  • 2011-02-11
  • 1970-01-01
  • 2012-06-27
相关资源
最近更新 更多