7

The following code to converts an IP to an int in a very fast way:

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

source

Question

How do I use bit shifting to convert the value back to an IP address?

Community
  • 1
  • 1
halfbit
  • 54,462
  • 46
  • 195
  • 426
  • possible duplicate of [How to convert an int to a little endian byte array?](http://stackoverflow.com/questions/2350099/how-to-convert-an-int-to-a-little-endian-byte-array) – Oliver Charlesworth Mar 19 '12 at 17:48
  • @OliCharlesworth I've tried `new IPAddress(BitConverter.GetBytes(i))` but that requires a different endian format than what my current approach offers – halfbit Mar 19 '12 at 17:49
  • 1
    A complete working answer is available here http://stackoverflow.com/a/9775647/328397 – halfbit Mar 19 '12 at 18:22

3 Answers3

4

Try the following

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;
}

Or to avoid an excessive number of out parameters, use a 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;
}

General Question: Why are you using int here instead of byte?

JaredPar
  • 673,544
  • 139
  • 1,186
  • 1,421
  • I intend to increment the IP address across class C subnet ranges, but I don't want to account for 255 in each octet in code. – halfbit Mar 19 '12 at 17:52
3

Assuming your code above is correct, simply reverse the bit-shifts and AND the result with 0xFF to drop spurious bits:

first = (ip >> 24) & 0xff;
second = (ip >> 16) & 0xff;
third = (ip >> 8) & 0xff;
fourth = ip & 0xff;
George Skoptsov
  • 3,572
  • 1
  • 22
  • 42
  • Thanks the 0xff is part of my issue. I need to learn why that is a special character. I'll bet it means EOF or null. – halfbit Mar 19 '12 at 17:53
  • @makerofthings7 `0xFF` represents a single byte where all of the bits are set to `1. The `& 0xFF` ensures that everything other than the least significant byte is set to `0` – JaredPar Mar 19 '12 at 17:54
1

For completeness (and as a way to give back to the community) this is how to convert a IP range to a list.

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);
        }

    }
}
halfbit
  • 54,462
  • 46
  • 195
  • 426