Solved

Sorting list of IP addresses

Posted on 2003-11-24
4
438 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
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…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
This is used to tweak the memory usage for your computer, it is used for servers more so than workstations but just be careful editing registry settings as it may cause irreversible results. I hold no responsibility for anything you do to the regist…

910 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

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now