2012-01-03 2 views
3

У меня есть задача выполнить в C#. У меня есть Subnet Mask: 255.255.128.0.Вычисление количества бит в маске подсети в C#

Мне нужно найти число битов в маске подсети, которая была бы, в данном случае 17.

Однако, мне нужно, чтобы быть в состоянии сделать это в C# без использования системы .Net библиотека (система, в которой я программирую, не имеет доступа к этой библиотеке).

Похоже, этот процесс должен быть что-то вроде:

1) Разделить маску подсети в Octets.

2) Преобразуйте октеты в двоичные.

3) Подсчитайте количество единиц в каждом октете.

4) Выведите общее количество найденных единиц.

Однако мой C# довольно беден. Кто-нибудь имеет знания C#, чтобы помочь?

+0

Это Хэмминг Вес – Bas

+1

Как именно вы используете C# без каких-либо библиотек BCL? Или вы имеете в виду конкретно 'System.Net' _namespace_? – Oded

+1

Итак, вы ничего не пробовали ни для одного из ваших 4 шагов? – sth

ответ

3

Бит подсчета алгоритма взяты из:
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); 

Самый простой алгоритм из статьи был использован. Если производительность имеет решающее значение, вы можете прочитать статью и использовать для нее более оптимизированное решение.

+0

Обратите внимание, что это решение даст тот же результат для «255.255.0.128» как для "255.255.128.0". Однако первая не является действительной маской подсети IPv4. Поэтому вы не можете использовать его для проверки маски. –

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; 
+0

Итак, чтобы ответить на вопрос, используйте вышеприведенную информацию для каждой части маски подсети. Если маска подсети является строкой, разделите ее на '.' И проанализируйте номер. Затем подсчитайте экземпляры 1 в строке, возможно, как «var onesInResult = result.replace (« 0 »,« ») .Length;' –

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

Полный образец:

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

Решение состоит в том, чтобы использовать 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=0, 1x1=1. Так что, если у нас есть некоторое гипотетическое число

0000101001 и умножить его на 1 (так в бинарном мире мы выполняем &), который nothig еще тогда 0000000001, мы получаем

0000101001 
0000000001 

Наиболее правая цифра 1 в обоих номерах, что делает binary AND возвращение 1, в противном случае, если ЛЮБОЙ цифр младший разряд будет 0, результатом будет 0.

Так вот, на линии total += oct & 1 добавить к tolal либо 1 или 0, на основе этого дига числа.

В строке {2}, вместо этого мы просто сдвигаем немного незначительные направо на самом деле, разделяющее число на 2, пока она становится 0.

Легко.

EDIT

Это справедливо для intgere и byte типов, но не использовать эту технику на floating point чисел. Кстати, это довольно ценное решение для этого вопроса.