Возникла такая задача, привычным движением руки взял и загуглил, может я еще плохо искать умею. но... не нашел, тот кровавый ###### который советуют люди на различных форумах заставил меня лить горючие слёзы. Пришлось делать все самому.
Нужно игнорировать советы вроде "Работай как со строкой", так как IP адрес - не строка, и выглядит так, как выглядит только по одной причине - читабельность.
IPv4 адрес - набор из 32х бит. Подробнее можно узнать по этой теме на специальности ИСиТ в конторе, ну или на худой конец в википедии.
Функция свертывания массива байтов в четырехбайтное целое.
Код:
private int CompressByteArray(byte[] bytes)
{
//Проверяем является ли массив подходящим для свертывания в int
if (bytes.Length != 4) throw new FormatException("Wrong IPv4 address");
int retval = 0; byte bit_shift = 0;
for (int i = bytes.Length - 1; i >= 0; i--)
{
//Прибавляем к финальному значению байты со сдвигом,
//зависящим от текущего элемента массива
retval += ((int)bytes[i]) << bit_shift;
bit_shift += 8;
}
return retval;
}
Этот и весь следующий код предназначен исключительно для ipv4, не было желания парить себя хранением 128 битовых адресов.
Функция развертывания целого числа в массив байтов.
Код:
private byte[] DecompressByteArray(int ip)
{
//Разбиваем целое число на байты
var bytes = BitConverter.GetBytes(ip);
//Разворачиваем в нужную последовательность
Array.Reverse(bytes);
return bytes;
}
Ну и наконец та функция, которая и будет выводить список всех адресов диапазона.
Код:
public IPAddress[] ExpandIpRange(IPAddress RangeFirst, IPAddress RangeLast)
{
//Сворачиваем байты адреса в целое число
var start_ip = (uint)(CompressByteArray(RangeFirst.GetAddressBytes()));
//Расчитываем дельту адресов(можно простым вычитанием, но xor логичнее и быстрее)
var delta = (uint)(CompressByteArray(RangeLast.GetAddressBytes()) ^ start_ip);
IPAddress[] retval = new IPAddress[delta+1];
//Создаем список адресов диапазона
//перебор осуществляется простым приращением
for (uint i = 0; i <= delta; i++)
//Разворачиваем число в массив байтов
//Создаем экземпляр Ip адреса и передаем массив в конструктор
//Добавляем адрес в список
try { retval[i] = new IPAddress(DecompressByteArray((int)(start_ip + i))); }
catch { continue; }
return retval;
}
Использование. Предположим, что у нас консольное приложение, функции описанные выше можно добавить сразу перед/после main.
Код:
static void Main(string[] args)
{
IPAddress addr = new IPAddress(new byte[] { 17, 0, 0, 1 });
IPAddress addr2 = new IPAddress(new byte[] { 17, 0, 2, 125 });
var t = new TestovyPoligon.Program();
var ips = t.ExpandIpRange(addr, addr2);
foreach (var ip in ips)
Console.WriteLine(ip.ToString());
}