【问题标题】:Calculating the number of bits in a Subnet Mask in C#在 C# 中计算子网掩码中的位数
【发布时间】:2019-01-23 16:46:26
【问题描述】:

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

我需要找到子网掩码中的位数,在本例中为 17。

但是,我需要能够在 C# 中执行此操作不使用 System.Net 库(我正在编程的系统无法访问此库)。

看起来这个过程应该是这样的:

1) 将子网掩码拆分为八位字节。

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

3) 计算每个八位字节中“一”的数量。

4) 输出找到的总数。

但是,我的 C# 很差。有谁有 C# 知识可以提供帮助吗?

【问题讨论】:

  • 在没有任何 BCL 库的情况下,您究竟如何运行 C#?或者你的意思是System.Net 命名空间
  • 那么您的 4 个步骤中的任何一个都没有尝试过?
  • 我已经尝试过并对其进行了哈希处理,但在尝试执行“byte octetByte = byte.Parse(octet);”之类的操作时遇到了困难

标签: c# mask subnet


【解决方案1】:

位计数算法取自:
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);

使用了文章中最简单的算法。如果性能至关重要,您可能需要阅读这篇文章并从中使用更优化的解决方案。

【讨论】:

  • 请注意,此解决方案对“255.255.0.128”的结果与对“255.255.128.0”的结果相同。然而,前者不是有效的 IPv4 子网掩码。所以你不能用它来验证掩码。
【解决方案2】:
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;

【讨论】:

    【解决方案3】:

    完整示例:

    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
    
            }
    

    【讨论】:

      【解决方案4】:

      您可以像这样将数字转换为二进制:

              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;
      【解决方案5】:

      解决方案是使用binary operation 之类的

        foreach(string octet in ipAddress.Split('.'))
        {       
            int oct = int.Parse(octet);     
            while(oct !=0) 
            {
                    total += oct & 1; // {1}
                    oct >>=1;  //{2}          
            }   
        }
      

      诀窍在于,在 {1} 线上,binary AND 是一个乘法,因此将 1x0=01x1=1 相乘。所以如果我们有一些假设的数字

      0000101001 乘以1(所以在二进制世界中我们执行&),这与0000000001 无关,我们得到

      0000101001
      0000000001
      

      两个数字中的大多数正确数字都是1,因此使binary AND返回1,否则如果ANY数字中的小数字将是0 ,结果将是0

      所以在这里,在total += oct &amp; 1 线上,我们根据该数字将10 添加到tolal

      {2} 行上,我们只是将 minor 位向右移动,实际上,将数字除以 2,直到变为 0 .

      简单。

      编辑

      这对intgerebyte 类型有效,但不要在floating point 数字上使用此技术。顺便说一句,对于 this 问题,这是非常有价值的解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-01-22
        • 1970-01-01
        • 2011-08-06
        • 1970-01-01
        • 2011-01-19
        • 1970-01-01
        相关资源
        最近更新 更多