Как заполнить 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]