Solved

Sorting list of IP addresses

Posted on 2003-11-24
4
453 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
[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
  • 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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
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…
If you're a developer or IT admin, you’re probably tasked with managing multiple websites, servers, applications, and levels of security on a daily basis. While this can be extremely time consuming, it can also be frustrating when systems aren't wor…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.

707 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