Как преобразовать адрес IPv4 в целое число в C #?

Я ищу функцию, которая преобразует стандартный IPv4-адрес в Integer. Бонусные точки доступны для функции, которая будет делать обратное.

Решение должно быть в C #.

20 Solutions collect form web for “Как преобразовать адрес IPv4 в целое число в C #?”

32-разрядные целые числа без знака являются адресами IPv4. Между тем, свойство IPAddress.Address , в то время как устарело, – это Int64, который возвращает 32-битное значение без знака IPv4-адреса (улов есть, он находится в сетевом порядке байтов, поэтому вам нужно поменять его).

Например, мой местный google.com находится по адресу 64.233.187.99 . Это эквивалентно:

 64*2^24 + 233*2^16 + 187*2^8 + 99 = 1089059683 

И действительно, http: // 1089059683 / работает как ожидалось (по крайней мере, в Windows, протестированном с IE, Firefox и Chrome, но не работает на iPhone).

Вот тестовая программа для показа обоих конверсий, включая обмен байтами сети / хоста:

 using System; using System.Net; class App { static long ToInt(string addr) { // careful of sign extension: convert to uint first; // unsigned NetworkToHostOrder ought to be provided. return (long) (uint) IPAddress.NetworkToHostOrder( (int) IPAddress.Parse(addr).Address); } static string ToAddr(long address) { return IPAddress.Parse(address.ToString()).ToString(); // This also works: // return new IPAddress((uint) IPAddress.HostToNetworkOrder( // (int) address)).ToString(); } static void Main() { Console.WriteLine(ToInt("64.233.187.99")); Console.WriteLine(ToAddr(1089059683)); } } 

@Barry Kelly и @Andrew Hare, на самом деле, я не думаю, что умножение – это самый ясный способ сделать это (все правильно).

IP-адрес «отформатированный» Int32 можно рассматривать как следующую структуру

 [StructLayout(LayoutKind.Sequential, Pack = 1)] struct IPv4Address { public Byte A; public Byte B; public Byte C; public Byte D; } // to actually cast it from or to an int32 I think you // need to reverse the fields due to little endian 

Итак, чтобы преобразовать ip-адрес 64.233.187.99, вы можете сделать:

 (64 = 0x40) < < 24 == 0x40000000 (233 = 0xE9) << 16 == 0x00E90000 (187 = 0xBB) << 8 == 0x0000BB00 (99 = 0x63) == 0x00000063 ---------- =| 0x40E9BB63 

поэтому вы можете добавить их с помощью + или вы могли бы использовать их или вместе. Результат в 0x40E9BB63, который составляет 1089059683. (На мой взгляд, глядя в шестнадцатеричном виде, гораздо проще увидеть байты)

Таким образом, вы можете написать функцию как:

 int ipToInt(int first, int second, int third, int fourth) { return (first < < 24) | (second << 16) | (third << 8) | (fourth); } 

Чтобы преобразовать из IPv4 в правильное целое число:

 IPAddress address = IPAddress.Parse("255.255.255.255"); byte[] bytes = address.GetAddressBytes(); Array.Reverse(bytes); // flip big-endian(network order) to little-endian uint intAddress = BitConverter.ToUInt32(bytes, 0); 

И чтобы вернуть обратно:

 byte[] bytes = BitConverter.GetBytes(4294967295); Array.Reverse(bytes); // flip little-endian to big-endian(network order) string ipAddress = new IPAddress(bytes).ToString(); 

Объяснение:

IP-адреса находятся в сетевом порядке (big-endian), в то время как int s являются малоподвижными в Windows, поэтому, чтобы получить правильное значение, вы должны поменять байты перед преобразованием.

Кроме того, даже для IPv4 int не может хранить адреса, превышающие 127.255.255.255 , например широковещательный адрес (255.255.255.255) , поэтому используйте uint .

Попробуйте это:

 private int IpToInt32(string ipAddress) { return BitConverter.ToInt32(IPAddress.Parse(ipAddress).GetAddressBytes().Reverse().ToArray(), 0); } private string Int32ToIp(int ipAddress) { return new IPAddress(BitConverter.GetBytes(ipAddress).Reverse().ToArray()).ToString(); } 

Поскольку никто не отправил код, который использует BitConverter и фактически проверяет соответствие, здесь идет:

 byte[] ip = address.Split('.').Select(s => Byte.Parse(s)).ToArray(); if (BitConverter.IsLittleEndian) { Array.Reverse(ip); } int num = BitConverter.ToInt32(ip, 0); 

и назад:

 byte[] ip = BitConverter.GetBytes(num); if (BitConverter.IsLittleEndian) { Array.Reverse(ip); } string address = String.Join(".", ip.Select(n => n.ToString())); 

Я столкнулся с некоторыми проблемами с описанными решениями, столкнувшись с IP-адресами с очень большим значением. Результатом было бы то, что байт [0] * 16777216 thingy переполнился бы и стал отрицательным значением int. что исправлено для меня, это простая операция литья типа.

 public static long ConvertIPToLong(string ipAddress) { System.Net.IPAddress ip; if (System.Net.IPAddress.TryParse(ipAddress, out ip)) { byte[] bytes = ip.GetAddressBytes(); return (long) ( 16777216 * (long)bytes[0] + 65536 * (long)bytes[1] + 256 * (long)bytes[2] + (long)bytes[3] ) ; } else return 0; } 

Мой вопрос был закрыт, я понятия не имею, почему. Принятый здесь ответ – это не то, что мне нужно.

Это дает мне правильное целочисленное значение для IP.

 public double IPAddressToNumber(string IPaddress) { int i; string [] arrDec; double num = 0; if (IPaddress == "") { return 0; } else { arrDec = IPaddress.Split('.'); for(i = arrDec.Length - 1; i >= 0 ; i = i -1) { num += ((int.Parse(arrDec[i])%256) * Math.Pow(256 ,(3 - i ))); } return num; } } 

Обратная функция Дэви Ландмана

 string IntToIp(int d) { int v1 = d & 0xff; int v2 = (d >> 8) & 0xff; int v3 = (d >> 16) & 0xff; int v4 = (d >> 24); return v4 + "." + v3 + "." + v2 + "." + v1; } 

Если вас заинтересовала функция, не просто ответ здесь, как это делается:

 int ipToInt(int first, int second, int third, int fourth) { return Convert.ToInt32((first * Math.Pow(256, 3)) + (second * Math.Pow(256, 2)) + (third * 256) + fourth); } 

с first по fourth – сегменты IPv4-адреса.

С UInt32 в правильном мало-endian формате, вот две простые функции преобразования:

 public uint GetIpAsUInt32(string ipString) { IPAddress address = IPAddress.Parse(ipString); byte[] ipBytes = address.GetAddressBytes(); Array.Reverse(ipBytes); return BitConverter.ToUInt32(ipBytes, 0); } public string GetIpAsString(uint ipVal) { byte[] ipBytes = BitConverter.GetBytes(ipVal); Array.Reverse(ipBytes); return new IPAddress(ipBytes).ToString(); } 
 public bool TryParseIPv4Address(string value, out uint result) { IPAddress ipAddress; if (!IPAddress.TryParse(value, out ipAddress) || (ipAddress.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork)) { result = 0; return false; } result = BitConverter.ToUInt32(ipAddress.GetAddressBytes().Reverse().ToArray(), 0); return true; } 
  public static Int32 getLongIPAddress(string ipAddress) { return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(IPAddress.Parse(ipAddress).GetAddressBytes(), 0)); } 

Вышеприведенный пример будет таким, каким я буду идти. Единственное, что вам может понадобиться сделать, – это преобразовать в UInt32 для целей показа или целые строки, включая использование его как длинного адреса в строковой форме.

Это то, что необходимо при использовании функции IPAddress.Parse (String). Вздох.

Скомпилировал несколько из приведенных выше ответов в метод расширения, который обрабатывает Endianness машины и обрабатывает адреса IPv4, которые были сопоставлены с IPv6.

 public static class IPAddressExtensions { ///  /// Converts IPv4 and IPv4 mapped to IPv6 addresses to an unsigned integer. ///  /// The address to conver /// An unsigned integer that represents an IPv4 address. public static uint ToUint(this IPAddress address) { if (address.AddressFamily == AddressFamily.InterNetwork || address.IsIPv4MappedToIPv6) { var bytes = address.GetAddressBytes(); if (BitConverter.IsLittleEndian) Array.Reverse(bytes); return BitConverter.ToUInt32(bytes, 0); } throw new ArgumentOutOfRangeException("address", "Address must be IPv4 or IPv4 mapped to IPv6"); } } 

Единичные тесты:

 [TestClass] public class IPAddressExtensionsTests { [TestMethod] public void SimpleIp1() { var ip = IPAddress.Parse("0.0.0.15"); uint expected = GetExpected(0, 0, 0, 15); Assert.AreEqual(expected, ip.ToUint()); } [TestMethod] public void SimpleIp2() { var ip = IPAddress.Parse("0.0.1.15"); uint expected = GetExpected(0, 0, 1, 15); Assert.AreEqual(expected, ip.ToUint()); } [TestMethod] public void SimpleIpSix1() { var ip = IPAddress.Parse("0.0.0.15").MapToIPv6(); uint expected = GetExpected(0, 0, 0, 15); Assert.AreEqual(expected, ip.ToUint()); } [TestMethod] public void SimpleIpSix2() { var ip = IPAddress.Parse("0.0.1.15").MapToIPv6(); uint expected = GetExpected(0, 0, 1, 15); Assert.AreEqual(expected, ip.ToUint()); } [TestMethod] public void HighBits() { var ip = IPAddress.Parse("200.12.1.15").MapToIPv6(); uint expected = GetExpected(200, 12, 1, 15); Assert.AreEqual(expected, ip.ToUint()); } uint GetExpected(uint a, uint b, uint c, uint d) { return (a * 256u * 256u * 256u) + (b * 256u * 256u) + (c * 256u) + (d); } } 

вот решение, которое я разработал сегодня (должен был сначала googled!):

  private static string IpToDecimal2(string ipAddress) { // need a shift counter int shift = 3; // loop through the octets and compute the decimal version var octets = ipAddress.Split('.').Select(p => long.Parse(p)); return octets.Aggregate(0L, (total, octet) => (total + (octet < < (shift-- * 8)))).ToString(); } 

Я использую LINQ, lambda и некоторые расширения в generics, поэтому, пока он производит тот же результат, он использует некоторые новые функции языка, и вы можете сделать это в трех строках кода.

У меня есть объяснение на моем блоге, если вам интересно.

приветствия, -jc

Я думаю, что это неправильно: «65536» ==> 0.0.255.255 «Должно быть:« 65535 »==> 0.0.255.255» или «65536» ==> 0.1.0.0 ”

@Davy Ladman ваше решение со сдвигом – это corrent, но только для ip, начинающегося с номера меньше или равного 99, infact первый octect должен быть отброшен до конца.

В любом случае конвертировать назад с длинным типом довольно сложно, потому что хранить 64 бит (не 32 для Ip) и заполнять 4 байта нулями

 static uint ToInt(string addr) { return BitConverter.ToUInt32(IPAddress.Parse(addr).GetAddressBytes(), 0); } static string ToAddr(uint address) { return new IPAddress(address).ToString(); } 

Наслаждайтесь!

Massimo

Предполагая, что у вас есть IP-адрес в строчном формате (например, 254.254.254.254)

 string[] vals = inVal.Split('.'); uint output = 0; for (byte i = 0; i < vals.Length; i++) output += (uint)(byte.Parse(vals[i]) << 8 * (vals.GetUpperBound(0) - i)); 
 var ipAddress = "10.101.5.56"; var longAddress = long.Parse(string.Join("", ipAddress.Split('.').Select(x => x.PadLeft(3, '0')))); Console.WriteLine(longAddress); 

Выход: 10101005056

 var address = IPAddress.Parse("10.0.11.174").GetAddressBytes(); long m_Address = ((address[3] < < 24 | address[2] << 16 | address[1] << 8 | address[0]) & 0x0FFFFFFFF); 

Взгляните на некоторые из безумных примеров синтаксического анализа в .Net IPAddress.Parse: ( MSDN )

“65536” ==> 0.0.255.255
“20.2” ==> 20.0.0.2
“20.65535” ==> 20.0.255.255
“128.1.2” ==> 128.1.0.2

  • Обеспечивает ли NAT безопасность?
  • Windows 7 ipv4 autoconfiguration - невозможно подключиться к Интернету
  • Установите версию протокола Интернета 4 (TCP / IPv4) в Windows 7
  • Подключение IPv4 к IPv6-only
  • Есть ли команда, которая позволяет мне установить предпочтительный IP-адрес для адаптера?
  • Как клиентские приложения знают, как использовать IPv4 или IPv6?
  • Почему я получаю «General Failure» при проверке имени хоста на узле Win 7 в сети?
  • Удалился бы NAT, преобразованный в ipv6?
  • Проверка адресов IPv4 с регулярным выражением
  • 6to4 против ISATAP vs Teredo Adapters
  • Дроссельная скорость загрузки нового маршрутизатора с Comcast (ipv6 vs ipv4)
  • Interesting Posts

    Поток аудио ПК в Skype

    Rsync с использованием regex для включения только некоторых файлов

    OwnCloud MySQL таблица «oc_filecache» повреждена, могу ли я ее восстановить?

    Проверка орфографии Firefox по умолчанию (и возврат) на неправильный язык

    Как масштабировать изображение в ImageView, чтобы сохранить соотношение сторон

    Как исследовать больше настроек по умолчанию для настройки на OS X?

    Неправильное соотношение сторон в mp4 (H.264), созданное камерой Samsung

    Планировщик задач Windows не запускает задачу в Windows 10

    В чем разница между classом и classом classа Scala?

    Есть ли способ заставить Outlook 2003 отправлять электронное письмо в определенное время, а не сразу?

    Двойные мониторы на Optiplex 755

    Восстановить из резервной копии истории файлов Windows 10 на новый компьютер?

    Запись доступа к OSX HDD из Ubuntu

    Как поддерживать различные размеры экрана в android

    Как восстановить файл, замененный другим файлом с тем же именем и размером

    Давайте будем гением компьютера.