Solved

# IP to Decimal and Decimal to IP

Posted on 2003-02-23
Medium Priority
1,929 Views
Does anyone have a function that converts an IP to Decimal and a function that converts the decimal back to IP

Thanks

0
Question by:alspivey
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• Learn & ask questions
• 8
• 7
• 3
• +6

LVL 101

Expert Comment

ID: 8006009
What is an IP?

mlmcc
0

Author Comment

ID: 8006077
Internet address i.e 192.168.0.1
0

LVL 84

Expert Comment

ID: 8006511
perl -e "print unpack'N',pack'C*',split/\./,shift" 192.168.0.1
perl -e "print join'.',unpack'C*',pack'N',shift" 3232235521
0

LVL 3

Expert Comment

ID: 8007098
in C/C++ try inet_aton:
inet_aton() converts the Internet host address cp from the standard numbers-and-dots notation into  binary  data  and
stores it in the structure that inp points to. inet_aton returns nonzero if the address is valid, zero if not.

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int inet_aton(const char *cp, struct in_addr *inp);
0

Expert Comment

ID: 8007407
heres an ip to decimal delphi function i made some time ago. Tho i dont quite know how to reverse it :P

var
Dec   : Array[1..4] of integer = (16777216,65536,256,1);

procedure ip2dec(ip:string; decimal: int64);
VAR ip             : Array[1..4] of Int64;
IPCut          : string;
Poz, i         : integer;
total          : int64;

begin
IPCut := ipstr;

i := 1;
While Pos('.', IPCut) > 0 Do
Begin
Poz := Pos('.', IPCut);
ip[i] := StrToInt( Copy(IPCut,1,Poz - 1));
Delete(IPCut, 1, Poz);
inc(i);
end;
ip[4] := StrToInt(IPCut);

Total := 0;
i := 1;
While i <= 4 do
begin
total := Total + ip[i] * dec[i];
inc(i);
end;
decimal := total;
end;
0

LVL 9

Expert Comment

ID: 8008915
Delphi code:

type
// since IPv4 address consists of four octets or simply dword
TIPv4 = record
a,b,c,d: byte;
end;

function IPv4ToInt(const IP: string): dword;
var
c, i, l: integer;
ba: array [0..3] of byte;
s: string;
begin
c := 0;
l := Length(IP);
for i := 1 to l do begin
if IP[i] <> '.' then
s := s + IP[i];
if (IP[i] = '.') or (i = l) then begin
ba[c] := StrToInt(s);
s := '';
inc(c);
end;
end;
Move(ba, Result, 4);
end;

function IntToIPv4(const IntIP: dword): string;
begin
with TIPv4(IntIP) do
Result := Format('%d.%d.%d.%d', [a, b, c, d]);
end;

wbr, mo.
0

Author Comment

ID: 8009553
Internet address i.e 192.168.0.1
0

LVL 9

Expert Comment

ID: 8009667
IPv4ToInt('192.168.0.1') will be 16820416.
IPv4 is in format xxx.xxx.xxx.xxx
where xxx is 8bit number (octet)

wbr, mo.
0

LVL 24

Expert Comment

ID: 8010688
done?
0

LVL 5

Expert Comment

ID: 8010801
I think, first you must specify what language you are using ;-). The following example (in Delphi) I used for my own needs:

uses
Splitter;

type
TIPAddress = packed record // IP-Ã Ã¤Ã°Ã¥Ã±
case Integer of
1: (A4, A3, A2, A1: Byte);
2: (A: Cardinal);
end;

function GetIPFromString(S: String): TIPAddress;
var
Splitter: TSplitter;
Code, A: Integer;
label 1;
begin
Result.A := 0;
Splitter := TSplitter.Create(S, '.', True);
if Splitter.Src = '' then Goto 1;
if Splitter.Count <> 4 then Goto 1;
if Splitter.S[0] = '*' then IP.A1 := 255 else
begin
Val(Splitter.S[0], A, Code);
if (Code <> 0) or (A < 0) or (A > 255) then Goto 1;
IP.A1 := A;
end;
if Splitter.S[1] = '*' then IP.A2 := 255 else
begin
Val(Splitter.S[1], A, Code);
if (Code <> 0) or (A < 0) or (A > 255) then Goto 1;
IP.A2 := A;
end;
if Splitter.S[2] = '*' then IP.A3 := 255 else
begin
Val(Splitter.S[2], A, Code);
if (Code <> 0) or (A < 0) or (A > 255) then Goto 1;
IP.A3 := A;
end;
if Splitter.S[3] = '*' then IP.A4 := 255 else
begin
Val(Splitter.S[3], A, Code);
if (Code <> 0) or (A < 0) or (A > 255) then Goto 1;
IP.A4 := A;
end;
Result := IP;
1:
Splitter.Free;
end;

function GetStringFromIP(IP: TIPAddress): String;
begin
Result := IntToStr(IP.A1) + '.' + IntToStr(IP.A2) + '.' + IntToStr(IP.A3) +
'.' + IntToStr(IP.A4);
end;

Splitter unit source may be obtainet here: http://www.serge.dsip.net/downloads/Splitter.pas

If you are using WinSock API you may prefer WinSock API native functions inet_addr and inet_ntoa (given C++ syntax):

char FAR * inet_ntoa (
);

unsigned long inet_addr (
const char   FAR *cp
);

See Platform SDK: Windows Sockets (MSDN) for details.
0

Expert Comment

ID: 8010934
i think he should choose the SHORT solution :P
0

Author Comment

ID: 8012389
Hi mocarts,

Your 2 functions work great. What I'm trying to do is calculate how many ip's are contained in a range of 2 address i.e 192.168.0.8 - 192.168.1.255. And I was thinking that converting them to decimal would alow me to subtract them to get the total count. (How wrong I was)
I also was trying to step through the IP's one by one by adding 1 to the decimal and then convert it back, but that want work. Any ideas on how to do something this.

p.s msa2003 I'm using Delphi
0

LVL 8

Expert Comment

ID: 8014742
u shud have specified the language of ur choice.. else everyday u'll get a solution in different programming language
0

LVL 9

Expert Comment

ID: 8015545
that's very simple.
example with functions provided above by me:

function CountIPs(const ipFrom, ipTo: string): int64;
var
ipf, ipt: TIPv4;
begin
Result := 0;
ipf := TIPv4(IPv4ToInt(ipFrom));
ipt := TIPv4(IPv4ToInt(ipTo));
Result := ((ipt.a-ipf.a)*16777216) + ((ipt.b-ipf.b)*65536)
+ ((ipt.c-ipf.c)*256) + (ipt.d-ipf.d) {+ 1};
// +1 - if you want to include ipFrom in range
end;

and function to increment by one IP:
procedure IncIPv4(var IP: TIPv4);
begin
if IP.d < 255 then Inc(IP.d)
else begin
IP.d := 0;
if IP.c < 255 then Inc(IP.c)
else begin
IP.c := 0;
if IP.b < 255 then Inc(IP.b)
else begin
IP.b := 0;
if IP.a < 255 then Inc(IP.a)
else IP.a := 0;
end;
end;
end;
end;

wbr, mo.
0

LVL 5

Expert Comment

ID: 8018293
Whacko: my solution is not big. It is universal. Because I used it to work with real sets of IP addresses.

You should use my unit the next way:

Count := Abs(GetIPFromString('192.168.0.8').A - GetIPFromString('192.168.1.255').A);

Very simple, isn't it ;-) ?

Mocart: Don't you think that there is no need to get values by multiplication? I think that the better way (which does exactly the same, but much faster) is to use packed record to set a byte of a double word ;-).

The shorter example (excluding masking and error checking) of GetIPFromString:

function GetIPFromString(S: String): TIPAddress;
var
Splitter: TSplitter;
Code: Integer;
begin
Splitter := TSplitter.Create(S, '.', True);
Val(Splitter.S[0], Result.A1, Code);
Val(Splitter.S[1], Result.A2, Code);
Val(Splitter.S[2], Result.A3, Code);
Val(Splitter.S[3], Result.A4, Code);
Splitter.Free;
end;
0

LVL 5

Expert Comment

ID: 8018346
And what is really better:

uses
WinSock;

function CountIPs(const ipFrom, ipTo: String): Integer;
begin
end;

The only one line of code ;-)

Whi don't I use Int64 - because IPv4 IP address is 32-bit!

htonl and inet_addr are WinSock API functions. inet_addr gets an IP address from it's string representation in reverse byte order. htonl converts it to normal byte order.
0

LVL 5

Expert Comment

ID: 8018371
Sorry,

uses
WinSock;

function CountIPs(const ipFrom, ipTo: String): Integer;
begin
end;
0

LVL 9

Accepted Solution

mocarts earned 800 total points
ID: 8019122
you are right msa2003! I have to change order of elements in my TIPv4 record.
there will be complete solution to convert to dword and back IP string.

type
{\$IFOPT R-}
{\$DEFINE RANGEOFF}
{\$ENDIF}
EInvalidIPString = class(Exception)
end;

TIPv4 = record
d,c,b,a: byte;
end;

function IPv4ToInt(const IP: string): dword;
var
c, i, l: integer;
ba: array [0..3] of byte;
s: string;
begin
c := 3;
l := Length(IP);
if l = 0 then raise EInvalidIPString.Create('Zero IP string length.');
try
for i := 1 to l do begin
if IP[i] <> '.' then
s := s + IP[i];
if (IP[i] = '.') or (i = l) then begin
{\$IFDEF RANGEOFF} {\$R+} {\$ENDIF}
ba[c] := StrToInt(s);
{\$IFDEF RANGEOFF} {\$R-} {\$UNDEF RANGEOFF} {\$ENDIF}
s := '';
dec(c);
end;
end;
except
raise EInvalidIPString.Create('Invalid IP string format.');
end;
if c <> -1 then
raise EInvalidIPString.Create('Invalid IP string format.');
Move(ba, Result, 4);
end;

function IntToIPv4(const IntIP: dword): string;
begin
with TIPv4(IntIP) do
Result := Format('%d.%d.%d.%d', [a, b, c, d]);
end;

to get count:
Count := IPv4ToInt(sIpTo) - IPv4ToInt(sIpFrom);

to increment:
IntToIPv4(IPv4ToInt(sIP)+1);

wbr, mo.
0

LVL 5

Expert Comment

ID: 8020202
Don't you think that alltrhough usage of WinSock unit (which is shipped with Delphi) is better:

To get a string from IP (now Delphi syntax):
function inet_ntoa(in: in_addr): String;

To get an IP from string:
function inet_addr(cp: string): Cardinal;

To increment the IP address:
function inc_ip(ip: string): string;
var
begin
end;
0

Expert Comment

ID: 8020803
no, cos if there's an old, or no winsock installed you might get errors :P also its always better to use code instead of (third party) components, because:
2. easier to debug cos you still know what you did.
3. users of your app wouldbt have to install extra dll's etc, just because you wanted to make an app the easy way.

if its only for personal use... just see for yourself, but i can recommend this to anyone who wants to "master" a programming language
0

LVL 5

Expert Comment

ID: 8023059
Yes, but i think different:
1. It is usefull to learn more about WinSock API, cos it is a native TCP/IP API
2. You still know what you did - dll's are already debugged :P
3. winsock32.dll is allwais provided with ANY 32-bit Windows system. If your system is not 32-bit, all these examples wouldn't work :P

Of course, the ways could be different. I think I provided both :-) So there is something to choose from ;-)

P. S. I could provide access to full code of my Utils unit (Splitter is just a part). This code provides extended functionality such as IP masked compare, IP sets, configuration and user management utilities etc. As a kernel it uses the functions provided ahead.
0

LVL 9

Expert Comment

ID: 8032117
since I use dword as result - function will work on 16, 32, 64 etc. bit systems.
of course Winsock is another way how to do it, but if you don't need Winsock why compile unit in app?
wbr, mo.
0

LVL 5

Expert Comment

ID: 8034457
mocarts: I noted that I had provided two different solutions. The first (with Splitter unit) doesn't use WinSock and is a part of a real billing system which is extremely stable and processes thowsands IP's every day ;-). Another solution uses functions already provided with Windows system.

Your solution will not work in 16-bit system ;-). Simoly bacause Delphi from version 2 generates ONLY 32-bit code ;-). Delphi (1) generates 16-bit code but doesn't has rather different syntax ;-).

There are the details. In the matter of fact there is not a market but a place where experts must exchange ;-).
0

LVL 9

Expert Comment

ID: 8034538
why did you think, code will not work on 16bit system? dword is 32bit on 16bit or on 32bit system it doesn't matter..
wbr, mo.
0

LVL 9

Expert Comment

ID: 8057845
0

LVL 5

Expert Comment

ID: 8059490
No thanx...
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilationâ€¦
When we want to run, execute or repeat a statement multiple times, a loop is necessary. This article covers the two types of loops in Python: the while loop and the for loop.
This video teaches viewers about errors in exception handling.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and â€¦
###### Suggested Courses
Course of the Month10 days, 23 hours left to enroll

#### 770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.