Для работы с 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. Поиск. | Персональный блог Толика Панкова