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
Solved

Sorting list of IP addresses

Posted on 2003-11-24
4
448 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:EddieShipman
  • 2
  • 2
4 Comments
 
LVL 3

Accepted Solution

by:
raidos earned 250 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:EddieShipman
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:EddieShipman
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: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

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

Suggested Solutions

Title # Comments Views Activity
Intraweb download file link ? 1 155
Delphi Form ownership 4 111
Tviruailstringtree sort multi columns on header click 1 74
how can i search if string exist in array ? 3 63
A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…

860 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