Reputation: 15805
Please consider this (non-homework) exercise of converting a slash-notation (e.g. 24, 30) to a subnet mask.
When I copy a BitArray
to byte[]
, the internal ordering of the BitArray
leads to incorrect output.
For instance, with an input of numberOfSetBits=24
, ToString()
should return 255.255.255.0
(this works because the bits are symmetrical).
However, an input of 30
results in 255.255.255.63
instead of the expected 255.255.255.252
.
Yes, I realize that that's just the way a BitArray handles it's children (there's an old discussion about the issue, unfortunately without a solution, just a never-ending argument over why one ordering would be better).
But how, for the love of god, can I get this code to treat 1111 1100
(=252) for what it is instead of mangling it to 0011 1111
(=63)? I believe I'll have to change the order in which I'm adding the bits in the first place, but I can't get it to work.
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);
}
}
Thank you.
Upvotes: 3
Views: 1768
Reputation: 700192
You don't need a BitArray
, you can create the mask from shifting an integer, and use BitConverter.GetBytes
to get it as bytes:
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);
}
Upvotes: 2
Reputation: 51319
Wouldn't this just be fixed by doing:
int bitPlace = 32;
for (int i = 0; i < numberOfSetBits; i++)
{
bits[--bitPlace] = true;
}
This sets the high-order bits (rather than the low-order bits). The reasoning here is precisely what is mentioned in the answer you linked- BitArray stores the least-significant digits in the lowest index, so the bit array 11111000000000
below is [indexed] thus:
(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]
Upvotes: 2