Calculating the number of bits in a Subnet Mask in C#

百般思念 提交于 2019-12-01 08:25:07

Bit counting algorithm taken from:
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;

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

        }

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;

The solution is to use a binary operation like

  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. 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
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.

So here, on line total += oct & 1 we add to tolal either 1 or 0, based on that digi number.

On line {2}, instead we just shift the minor bit to right by, actually, deviding the number by 2, untill it becomes 0.

Easy.

EDIT

This is valid for intgere and for byte types, but do not use this technique on floating point numbers. By the way, it's pretty valuable solution for this question.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!