Как я могу использовать BitShifting для преобразования IP-адреса на основе int обратно в строку? - PullRequest
7 голосов
/ 19 марта 2012

Следующий код для быстрого преобразования IP в int:

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

source

Вопрос

Как использовать битовое смещение для преобразования значения обратно в IP-адрес?

Ответы [ 3 ]

4 голосов
/ 19 марта 2012

Попробуйте следующее

static out intToIp(int ip, out int first, out int second, out int third, out int fourth) {
  first = (ip >> 24) & 0xFF;
  second = (ip >> 16) & 0xFF;
  third = (ip >> 8) & 0xFF;
  fourth = ip & 0xFF;
}

Или, чтобы избежать чрезмерного количества выходных параметров, используйте struct

struct IP {
  int first;
  int second; 
  int third;
  int fourth;
}

static IP intToIP(int ip) {
  IP local = new IP();
  local.first = (ip >> 24) & 0xFF;
  local.second = (ip >> 16) & 0xFF;
  local.third = (ip >> 8) & 0xFF;
  local.fourth = ip & 0xFF;
  return local;
}

Общий вопрос: Почему вы используете int здесьвместо byte?

3 голосов
/ 19 марта 2012

Предполагая, что ваш код выше верен, просто измените битовые сдвиги и И результат с 0xFF, чтобы сбросить паразитные биты:

first = (ip >> 24) & 0xff;
second = (ip >> 16) & 0xff;
third = (ip >> 8) & 0xff;
fourth = ip & 0xff;
1 голос
/ 19 марта 2012

Для полноты (и как способ вернуть сообществу) это как конвертировать IP диапазон к списку.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;

namespace NormalizeIPRanges
{
    class Program
    {
        static void Main(string[] args)
        {

            if (!BitConverter.IsLittleEndian)
                // http://stackoverflow.com/a/461766/328397
                throw new NotSupportedException ("This code requires a little endian CPU");

            // IPv4
            string input = "64.233.187.98 - 64.233.188.2";
            var ipRange = input.Replace(" ", "").Split("-".ToCharArray());

            if (ipRange.Length == 2)
            {
                var startBytes =IPAddress.Parse(ipRange[0]).GetAddressBytes();
                var stopBytes = IPAddress.Parse(ipRange[1]).GetAddressBytes();

                if (startBytes.Length != 4  || stopBytes.Length != 4)
                {
                    // Note this implementation doesn't imitate all nuances used within MSFT IP Parsing
                    // ref: http://msdn.microsoft.com/en-us/library/system.net.ipaddress.parse.aspx

                    throw new ArgumentException("IP Address must be an IPv4 address");
                }

                // IP addresses were designed to do bit shifting: http://stackoverflow.com/a/464464/328397
                int startAddress = ipToInt(startBytes[0], startBytes[1], startBytes[2], startBytes[3]);
                var t  =intToIP(startAddress);

                int stopAddress = ipToInt(stopBytes[0], stopBytes[1], stopBytes[2], stopBytes[3]);
                var tr = intToIP(stopAddress);


                for (int i = startAddress; i <= stopAddress; i++)
                { 
                    Console.WriteLine(intToIP(i));
                }
            }
        }

        static int ipToInt(int first, int second, int third, int fourth)
        {
            return (first << 24) | (second << 16) | (third << 8) | (fourth);
        }
        static string intToIP(int ip)
        {
            var a = ip >> 24 & 0xFF;
            var b = ip >> 16 & 0xFF;
            var c = ip >> 8 & 0xFF;
            var d = ip & 0xFF;

            return String.Format("{0}.{1}.{2}.{3}",a,b,c,d);
        }

    }
}
...