Для работы с IP-адресами в .NET Framework есть класс IPAddress
из пространства имен System.Net
bool IsIP(string IP) { try { IPAddress addr = IPAddress.Parse(IP); } catch { return false; } return true; }
Класс IPAddress
и его функция Parse
распознает сокращенную форму записи IP-адреса, например, адрес 4.0.0.1
можно записать как 4.1
, и он будет таки корректным. Функция ToString()
класса IPAddress
всегда возвращает строку IP-адреса в полном виде, т.е. n.n.n.n
, это можно использовать для преобразования адреса в полную форму записи:
string ToStandForm(string IP) { if (!IsIP(IP)) { return string.Empty; } IPAddress addr = IPAddress.Parse(IP); return addr.ToString(); }
byte[] GetBytesBE(string IP) { IPAddress addr = IPAddress.Parse(IP); return addr.GetAddressBytes(); }
Примечание: GetAddressBytes()
выдает байты IP-адреса всегда в сетевом порядке, т.е. big-endian, в таком же, в котором байты идут при обычной записи IP. Если вдруг понадобится little-endian порядок, например, для того, чтобы преобразовать IP-адрес в целое число на little-endian системе, то массив надо перевернуть.
byte[] GetBytesLE(string IP) { IPAddress addr = IPAddress.Parse(IP); byte[] addrbytes = addr.GetAddressBytes(); Array.Reverse(addrbytes); return addrbytes; }
Аналог PHP-функции ip2long()
или сишной inet_addr()
int IPToInt32(string IP) { IPAddress addr = IPAddress.Parse(IP); //получаем байты адреса, они всегда в big-endian byte[] addrbytes = addr.GetAddressBytes(); //IP в виде Int32 big-endian int n = BitConverter.ToInt32(addrbytes,0); //если в системе little-endian порядок if (BitConverter.IsLittleEndian) { n = IPAddress.NetworkToHostOrder(n); //надо перевернуть } return n; }
Изменить порядок байт можно и без использования Array.Reverse()
, если число типа short
или int
. Для этого в классе IPAddress
присутствуют функции NetworkToHostOrder()
, которая меняет порядок байт в переменной с сетевого (big-endian) на используемый на локальной машине, и функция HostToNetworkOrder()
, которая делает обратную операцию.
Скорее, чтоб два раза не вставать, делается точно так же, как и преобразование в знаковый int
, но функции NetworkToHostOrder()
и HostToNetworkOrder()
тут уже не помогут, так что придется переворачивать массив байт адреса с помощью Array.Reverse()
:
public static uint IPToUInt32(string IP) { IPAddress addr = IPAddress.Parse(IP); byte[] addrbytes = addr.GetAddressBytes(); if (BitConverter.IsLittleEndian) { Array.Reverse(addrbytes); } return BitConverter.ToUInt32(addrbytes, 0); }
Навеяно вопросом на stackowerflow
Объединил все вышеуказанные функции в отдельный класс.
Pingback: C#, проверка попадания IP-адреса в зарезервированные диапазоны. | Персональный блог Толика Панкова
Pingback: SxGeoSharp. Интерфейс на C# для базы данных SypexGeo. — Часть II. Поиск. | Персональный блог Толика Панкова