Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

Sorting list of IP addresses

Posted on 2003-11-24
4
Medium Priority
?
457 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 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: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

[Webinar] Lessons on Recovering from Petya

Skyport is working hard to help customers recover from recent attacks, like the Petya worm. This work has brought to light some important lessons. New malware attacks like this can take down your entire environment. Learn from others mistakes on how to prevent Petya like worms.

Question has a verified solution.

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

Introduction The parallel port is a very commonly known port, it was widely used to connect a printer to the PC, if you look at the back of your computer, for those who don't have newer computers, there will be a port with 25 pins and a small print…
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…
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
In this video, Percona Solutions Engineer Barrett Chambers discusses some of the basic syntax differences between MySQL and MongoDB. To learn more check out our webinar on MongoDB administration for MySQL DBA: https://www.percona.com/resources/we…
Suggested Courses

636 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