[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Sorting list of IP addresses

Posted on 2003-11-24
4
Medium Priority
?
460 Views
Last Modified: 2010-05-18
I am extremely surprised to not find a standard IP address sorting routine in Delphi. I search high and low
and couldn't find one so I started writing one myself. I found a couple written in Perl, but I'm definately
not THAT much of a geek and they used many built in Perl functions not avail in Delphi. I also found an
insertion sort routine in C that used inet_addr from the winsock library and figured I could do something
like that in Delphi.

Anyway...I came up something but it doesn't work correctly all the time and I can not understand why.

Here is a shortened copy that only compares two IP addresses and returns the larger of the two.

function CompareIPs(IP1, IP2: String):String;
var
  a, b: TInAddr;
begin
  Result := '';
  a.S_addr := inet_addr(PChar(IP1));
  b.S_addr := inet_addr(PChar(IP2));
  if a.S_addr > b.S_addr then
    Result := inet_ntoa(a)
  else
    Result := inet_ntoa(b);
end;

Lable1.Caption := CompareIPs('224.123.161.5', '203.124.162.10');

returns the 203.124.162.10 address. Go figure...

Can someone help me figure out what the hell is going on here and why it is returning
the wrong result, or am I just wrong in assuming that it is returning the wrong result.
0
Comment
Question by:Eddie Shipman
  • 2
  • 2
4 Comments
 
LVL 3

Accepted Solution

by:
raidos earned 1000 total points
ID: 9811452
Inet_addr, breaks ip down and puts it into a 32 bit integer...
my best guess it that it puts it in a byte order that is the opposite of what you would want for your function to work....

this is what i came up with...should work in all cases.. ;P

function CompareIps(IP1, IP2: string): string;
Type
  ByteArr = packed array[1..4] of Byte;
Var
  a, b: TInAddr;
  CompVar: Integer;
Begin
  CompVar := 0;
  a.S_addr := inet_addr(PChar(IP1));
  b.S_Addr := inet_addr(PChar(IP2));
  if ByteArr(a.S_addr)[1] <> ByteArr(b.S_addr)[1] then Begin
    if ByteArr(a.S_addr)[1] < ByteArr(b.S_addr)[1] Then
      Inc(CompVar)
    Else
      Dec(CompVar);
  end else Begin
    if ByteArr(a.S_addr)[2] <> ByteArr(b.S_addr)[2] then Begin
      if ByteArr(a.S_addr)[2] < ByteArr(b.S_addr)[2] Then
        Inc(CompVar)
      Else
        Dec(CompVar);
    end else Begin
       if ByteArr(a.S_addr)[3] <> ByteArr(b.S_addr)[3] then Begin
         if ByteArr(a.S_addr)[3] < ByteArr(b.S_addr)[3] Then
           Inc(CompVar)
         Else
           Dec(CompVar);
       end else Begin
         if ByteArr(a.S_addr)[4] <> ByteArr(b.S_addr)[4] then Begin
           if ByteArr(a.S_addr)[4] < ByteArr(b.S_addr)[4] then
             Inc(CompVar)
           Else
             Dec(CompVar);
         end else begin
           //Do nothing, IP's are the same
         end;
       end;
    end;
  end;
  if CompVar > 0 then
    Result := IP2
  else if CompVar < 0 Then
    Result := IP1
  else
    Result := 'EQUAL';
end;

Regards
//raidos
0
 
LVL 26

Author Comment

by:Eddie Shipman
ID: 9811526
Thanks for pointing out to me what the byte ordering meant.
0
 
LVL 3

Expert Comment

by:raidos
ID: 9811719
Actually after thinking abit and consulting a colleague i realized that the problem is actually a bug in Winsock.pas where
u_long is defined as longint....

should have been defined as DWord i think otherwise the sign bit will be in play during comparison.

but then again i'm not sure..

what i'm sure of is that my function should work anyway.. ;P

Regards
//raidos
0
 
LVL 26

Author Comment

by:Eddie Shipman
ID: 9811961
Found a much shorter way to do it but I'll let you keep the points anyway...;-)

function CompareIps(IP1, IP2: string): string;
var
  a, b: TInAddr;
begin
  a.S_addr := inet_addr(PChar(IP1));
  b.S_Addr := inet_addr(PChar(IP2));
  if ntohl(a.S_addr) > ntohl(b.S_addr) then
    Result := IP1
  else if ntohl(b.S_addr) > ntohl(a.S_addr) then
    Result := IP2
  else
    Result := 'EQUAL';
end;

The ntohl function reverses the byte ordering for me.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Suggested Courses
Course of the Month18 days, 7 hours left to enroll

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

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

Join & Ask a Question