Как заполнить BitArray, чтобы сработало его копирование в байт

Пожалуйста, рассмотрите это (не домашнее задание) упражнение преобразования косой черты (например, 24, 30) в маску подсети.

Когда я копирую BitArray в byte[] Внутренний порядок BitArray приводит к неверному выводу.

Например, с вводом numberOfSetBits=24, ToString() должен вернуться 255.255.255.0 (это работает, потому что биты симметричны). Тем не менее, вход 30 результаты в 255.255.255.63 вместо ожидаемого 255.255.255.252, Да, я понимаю, что именно так BitArray обрабатывает своих детей (существует давняя дискуссия по этому вопросу, к сожалению, без решения, просто бесконечный аргумент о том, почему один порядок будет лучше).

Но как, ради бога, я могу заставить этот код лечить 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);
    }
}

Спасибо.

2 ответа

Решение

Вам не нужен 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);
}

Разве это не было бы исправлено, выполнив:

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

Это устанавливает биты старшего разряда (а не биты младшего разряда). Причина заключается именно в том, что упомянуто в ответе, который вы связали: BitArray хранит младшие значащие цифры в самом нижнем индексе, поэтому битовый массив 11111000000000 ниже [индексируется] таким образом:

(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]
Другие вопросы по тегам