在C#中计算子网掩码的位数

3

我有一个C#任务需要完成。我有一个子网掩码:255.255.128.0。

我需要找到子网掩码中的位数,即在这种情况下为17。

然而,我需要能够在C#中不使用System.Net库(我正在编程的系统无法访问此库)来完成此操作。

似乎应该按照以下步骤进行:

1)将子网掩码分成八位组。

2)将八位组转换为二进制。

3)计算每个八位组中的1的数量。

4)输出找到的所有1的总数。

然而,我的C#水平比较差。有没有人有C#知识可以帮助?


1
你是如何在没有任何BCL库的情况下运行C#的?或者你特指 System.Net 命名空间吗? - Oded
1
那么你还没有尝试过你的四个步骤中的任何一个吗? - sth
优雅地判断是否有多个布尔值为“true” - Devendra D. Chavan
我曾经尝试过并搞砸了,当我试图执行"byte octetByte = byte.Parse(octet);"时遇到了困难。 - QuietLeni
5个回答

4

取自以下网址的位计数算法:
http://www.necessaryandsufficient.net/2009/04/optimising-bit-counting-using-iterative-data-driven-development/

string mask = "255.255.128.0";
int totalBits = 0;
foreach (string octet in mask.Split('.'))
{
    byte octetByte = byte.Parse(octet);
    while (octetByte != 0)
    {
        totalBits += octetByte & 1;     // logical AND on the LSB
        octetByte >>= 1;            // do a bitwise shift to the right to create a new LSB
    }                
}
Console.WriteLine(totalBits);

本文使用了最简单的算法。如果性能很重要,您可能希望阅读该文章并从中选择更优化的解决方案。

1
请注意,该解决方案对于“255.255.0.128”和“255.255.128.0”将给出相同的结果。然而,前者不是有效的IPv4子网掩码。因此,您不能使用它来验证掩码。 - Peter M

1
string ip = "255.255.128.0";
string a = "";
ip.Split('.').ToList().ForEach(x => a += Convert.ToInt32(x, 2).ToString());
int ones_found = a.Replace("0", "").Length;

0
你可以像这样将一个数字转换为二进制:
        string ip = "255.255.128.0";
        string[] tokens = ip.Split('.');
        string result = "";
        foreach (string token in tokens)
        {
            int tokenNum = int.Parse(token);
            string octet = Convert.ToString(tokenNum, 2);
            while (octet.Length < 8)
                octet = octet + '0';
            result += octet;
        }
        int mask = result.LastIndexOf('1') + 1;

因此,为了回答这个问题,请对子网掩码的每个部分使用上述方法。如果子网掩码是一个字符串,请在“.”上进行拆分并解析数字。然后,计算字符串中1的实例数量,可以使用var onesInResult = result.replace("0", "").Length; - George Duckett

0
一个完整的示例:
public int CountBit(string mask)
        {

            int ones=0;
            Array.ForEach(mask.Split('.'),(s)=>Array.ForEach(Convert.ToString(int.Parse(s),2).Where(c=>c=='1').ToArray(),(k)=>ones++));
          return ones

        }

0
解决方案是使用类似于二进制操作的方法。
  foreach(string octet in ipAddress.Split('.'))
  {       
      int oct = int.Parse(octet);     
      while(oct !=0) 
      {
              total += oct & 1; // {1}
              oct >>=1;  //{2}          
      }   
  }

诀窍在于第{1}行的二进制与实际上是一种乘法,因此乘以1x0=01x1=1。所以如果我们有一个假设的数字

0000101001并将其乘以1(在二进制世界中执行&),即0000000001,我们得到

0000101001
0000000001

两个数字的最右边位都是1,因此进行二进制AND运算会返回1,否则如果任何一个数字的最小位为0,结果将为0

所以,在这里,我们在total += oct & 1行中根据该数字添加10tolal中。

在第{2}行中,我们只需将最小位向右移动,实际上通过除以2来使数字变为0

很容易。

编辑

这适用于intgerebyte类型,但不要在浮点数上使用此技术。顺便说一句,这是这个问题的非常有价值的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接