简体   繁体   English

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

[英]Calculating the number of bits in a Subnet Mask in C#

I have a task to complete in C#.我有一个任务要在 C# 中完成。 I have a Subnet Mask: 255.255.128.0.我有一个子网掩码:255.255.128.0。

I need to find the number of bits in the Subnet Mask, which would be, in this case, 17.我需要找到子网掩码中的位数,在本例中为 17。

However, I need to be able to do this in C# WITHOUT the use of the System.Net library (the system I am programming in does not have access to this library).但是,我需要能够在不使用 System.Net 库的情况下在 C# 中执行此操作(我正在编程的系统无法访问该库)。

It seems like the process should be something like:这个过程似乎应该是这样的:

1) Split the Subnet Mask into Octets. 1) 将子网掩码拆分为八位字节。

2) Convert the Octets to be binary. 2) 将八位字节转换为二进制。

3) Count the number of Ones in each Octet. 3) 计算每个八位字节中 1 的数量。

4) Output the total number of found Ones. 4) 输出找到的总数。

However, my C# is pretty poor.但是,我的 C# 很差。 Does anyone have the C# knowledge to help?有没有人有 C# 知识可以提供帮助?

Bit counting algorithm taken from:位计数算法取自:
http://www.necessaryandsufficient.net/2009/04/optimising-bit-counting-using-iterative-data-driven-development/ 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);

The most simple algorithm from the article was used.使用了文章中最简单的算法。 If performance is critical, you might want to read the article and use a more optimized solution from it.如果性能至关重要,您可能需要阅读这篇文章并从中使用更优化的解决方案。

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;

You can convert a number to binary like this:您可以像这样将数字转换为二进制:

        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;

A complete sample:一个完整的样本:

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

        }

The solution is to use a binary operation like解决方案是使用binary operation

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

The trick is that on line {1} the binary AND is in sence a multiplication so multiplicating 1x0=0 , 1x1=1 .诀窍在于,在行{1} 上binary AND 1x0=0是一个乘法,因此乘以1x0=0 , 1x1=1 So if we have some hypothetic number所以如果我们有一些假设数

0000101001 and multiply it by 1 (so in binary world we execute &), which is nothig else then 0000000001 , we get 0000101001并将其乘以1 (因此在二进制世界中我们执行 &),然后是0000000001 ,我们得到

0000101001
0000000001

Most right digit is 1 in both numbers so making binary AND return 1 , otherwise if ANY of the numbers minor digit will be 0 , the result will be 0 .两个数字中最右边的数字都是1 ,因此进行binary AND返回1 ,否则如果任何数字的次要数字为0 ,则结果将为0

So here, on line total += oct & 1 we add to tolal either 1 or 0 , based on that digi number.所以在这里,在total += oct & 1线上total += oct & 1我们根据该数字数字将10添加到tolal

On line {2} , instead we just shift the minor bit to right by, actually, deviding the number by 2 , untill it becomes 0 .在行{2} 上,我们只是将次要位右移,实际上是将数字除以2 ,直到它变为0

Easy.简单。

EDIT编辑

This is valid for intgere and for byte types, but do not use this technique on floating point numbers.这对intgerebyte类型有效,但不要在floating point使用此技术。 By the way, it's pretty valuable solution for this question.顺便说一句,对于这个问题,这是非常有价值的解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM