×

Loading...
Ad by
  • 最优利率和cashback可以申请特批,好信用好收入offer更好。请点链接扫码加微信咨询,Scotiabank -- Nick Zhang 6478812600。
Ad by
  • 最优利率和cashback可以申请特批,好信用好收入offer更好。请点链接扫码加微信咨询,Scotiabank -- Nick Zhang 6478812600。

My clumsy perl implementation ... all most no error checking ... with some effort you should be able to get it under 25 lines (currently ~40 lines).

本文发表在 rolia.net 枫下论坛<pre>
===============
#!/usr/bin/perl

while (<>) {
$low = limit(1, getipmask($_));
$high = limit(0, getipmask($_));
open(MYIPS,"./ips.txt") || die "open err\n";
while (<MYIPS>) {
if ($low >= limit(0, getipmask($_)) && $high <= limit(1, getipmask($_))) {
print "Found: ", $_, "\n";
}
}
close MYIPS;
}

sub limit {
($highlow, $mask, @octet) = @_;
my $ip = 0;
for ($i=0; $i<4; $i++) {
$ip += $octet[$i]*256**(3-$i);
}
$ip = $ip & (2 ** 32 - 2 ** (32-$mask));
if ($highlow == 1) {
return $ip + 2 ** (32-$mask) - 1;
} else {
return $ip;
}
}

sub getipmask {
chomp;
if ($_ =~ /\//) {
($myip, $mymask) = split (/\//, $_);
} else {
$myip = $_;
$mymask = 32;
}
return($mymask, split (/\./, $myip));
}
===============
</pre>更多精彩文章及讨论,请光临枫下论坛 rolia.net
Report

Replies, comments and Discussions:

  • 工作学习 / IT技术讨论 / 请开发一个这样的实用的TOOLS,各位自认称职的SYS/NET ADMIN or Developer 请进
    目的是输入一个ip地址或地址段
    然后在一个保存有许多IP地址和地址段的文本文件中查找
    看此地址/地址段是否<b>包含</b>在其中

    比如以下是保存有许多IP地址和地址段的文本文件 — ips.txt
    182.3.58.0/23
    192.168.172.0/22
    127.0.0.0
    188.54.0.0/15
    ...
    ...

    输入
    127.0.0.0
    输出
    Found: 127.0.0.0
    输入
    127.0.0.1
    输出
    Not Found.

    输入
    182.3.59.223
    输出
    Found:182.3.58.0/23
    输入
    182.3.59.8/27
    输出
    Found:182.3.58.0/23
    .....
    .....

    编程的语言不限
    (最好是 ShellScript, PERL or Java ). 跨平台嘛
    结构越简单越好(算法不限)

    挺有用也挺有趣吧。
    做Sys Net Admin 的,别丢脸哦
    • 俺不是什么啊命,但是你这个问题确实简单得不得了
      我现在不想马上告诉你,否则的话你印象不深
    • use NT/2000 script, it is not big deal.
    • here is one implementation. It is really simple. Why don't you do it yourself??
      • I am not challenging anyone. Programming a simple tool is full of FUN and good exercise to your brain, right? If you Wrote that tool, could you share your source code here. Thanks.
        • You should really think about it yourself since this is so so so simple.
        • don't know why you don't develop it by yourself. As Smartiecat said, it is so so simple. Anyway, go to the same place for the source code in VC++ 6.0.
          • Hahaaha, the code is 'so simple so naive :)' but wrong
            It is what in the VC++ program to do the search:

            while ( m_ipFile.ReadString(lineBuffer) )
            {
            if ( lineBuffer.GetLength() < 1 )
            continue;

            nPos = lineBuffer.Find(m_ip, 0);
            if ( nPos != -1 )
            {
            lineBuffer.Insert(0, "Found:");
            m_resultList.AddString(lineBuffer);
            break;
            }
            }
            if ( nPos == -1 )
            {
            lineBuffer.Format("%s : Not Found", m_ip);
            m_resultList.AddString(lineBuffer);
            }

            PLEASE read my descriptions of the question
            Can it find
            182.3.59.8/27
            and show output of
            182.3.58.0/23??

            It is simple, but not as simple as your program. :)
            • I have no knowledge of system admin, and I don't understand the last example of your requirement, the input 182.3.59.8/27 and output 182.3.58.0/23.
              To me, they are totally different two strings and the result should be: "Not Found". Please comment.
              • Sorry for confusing you. 182.3.59.96/27 means ip block 182.3.59.96 netmask bits length is 27 bits long ( 255.255.255.224 ). ALL Network vendors now use this way to descript IP blocks.
                • I see. So the real requirement is: if netmask bits is specified by "/##", find out the entry which has the same netmask. Otherwise, find the exact entry. Is my understanding correct?
                  • partially correct. but still not that Simple :). For example: IP/IP Blocks "182.3.59.96/27 , 182.3.59.214, 182.3.59.8/28 ....." are all in the IP block 182.3.58.0/23. Not as simple as you thought. right? :)
                    • one question before I continue: /23 means the first 23 bits in the IP address, right?
                      • Right. TCP/IP fundamental
                    • the first 23 bits starting from MSB.
                    • version 1.1 done. Please go to the same location for the exe. Check whether it meets the requirement. I read about the netMask long ago, and almost forgot it already.
                      • It is OK, could you show the source code. just want to see the algorithm. A minor flaw in your program, it should show ALL the matched entries. But that is OK.
                        • here you go. It doesn't show all the matches because I return once a match is found. You want all the matches?
                          本文发表在 rolia.net 枫下论坛void CIpSearchDlg::OnSearchBtn()
                          {
                          // to do a search, a ip address file must have been opened,
                          // and the ip address to be searched must have been keyed in
                          UpdateData(TRUE);

                          BYTE inField1, inField2, inField3, inField4, inMaskBits;
                          DWORD inIp, inMask;

                          BYTE field1, field2, field3, field4, maskBits;
                          DWORD Ip, Mask;

                          DWORD MaskWhenCompare;

                          int nRet;

                          if ( m_ip.IsEmpty() == TRUE )
                          {
                          MessageBox("Specify the IP address to be searched.",
                          NULL, MB_ICONEXCLAMATION | MB_OK );
                          return;
                          }
                          else
                          {
                          nRet = sscanf(m_ip, "%d.%d.%d.%d/%d",
                          &inField1, &inField2, &inField3, &inField4, &inMaskBits);
                          if ( nRet < 4 )
                          {
                          MessageBox("The specified IP address is not valid.",
                          NULL, MB_ICONEXCLAMATION | MB_OK);
                          return;
                          }

                          if ( nRet == 5 )
                          {
                          if ( inMaskBits > 32 )
                          {
                          MessageBox("The specified IP address mask is not valid.",
                          NULL, MB_ICONEXCLAMATION | MB_OK);
                          return;
                          }
                          // netmask is specified
                          inMask = MakeNetMask(inMaskBits);
                          }
                          else
                          inMask = 0;

                          inIp = MakeDWord(inField1, inField2, inField3, inField4);
                          }

                          if ( m_ipFile.m_hFile == CFile::hFileNull )
                          {
                          MessageBox("Specify the IP address file to search in.",
                          NULL, MB_ICONEXCLAMATION | MB_OK );
                          return;
                          }

                          // do the string search
                          BeginWaitCursor();

                          m_ipFile.SeekToBegin();
                          CString lineBuffer;
                          BOOL found = FALSE;
                          while ( m_ipFile.ReadString(lineBuffer) )
                          {
                          if ( lineBuffer.GetLength() < 1 )
                          continue;

                          nRet = sscanf(lineBuffer, "%d.%d.%d.%d/%d",
                          &field1, &field2, &field3, &field4, &maskBits);
                          if ( nRet < 4 )
                          continue;

                          if ( nRet == 5 )
                          {
                          if ( maskBits > 32 )
                          continue;

                          Mask = MakeNetMask(maskBits);
                          }
                          else
                          Mask = 0;

                          Ip = MakeDWord(field1, field2, field3, field4);

                          if ( inMask || Mask )
                          {
                          if ( inMask && Mask )
                          MaskWhenCompare = inMask > Mask? Mask : inMask;
                          else if ( inMask )
                          MaskWhenCompare = inMask;
                          else
                          MaskWhenCompare = Mask;
                          }
                          else
                          MaskWhenCompare = MakeNetMask(32); // this can be made as a constant global
                          // for a better speed performance

                          if ( (Ip & MaskWhenCompare) == (inIp & MaskWhenCompare) )
                          {
                          CString displayMsg;
                          displayMsg = m_ip + " ==> Found: " + lineBuffer;
                          m_resultList.AddString(displayMsg);
                          found = TRUE;
                          break;
                          }
                          }
                          if ( !found )
                          {
                          lineBuffer.Format("%s ==> Not Found", m_ip);
                          m_resultList.AddString(lineBuffer);
                          }

                          m_resultList.SetCurSel(m_resultList.GetCount() - 1);

                          EndWaitCursor();
                          }更多精彩文章及讨论,请光临枫下论坛 rolia.net
                          • It is good. The algorithm is quite straight forward. Just another minor flaw:
                            If I input 127.0.0.0/8
                            it will show: Found-> 127.0.0.1
                            It is not correct
                            because 127.0.0.0/8 is not INCLUDED in 127.0.0.1
                            (127.0.0.1 is included in 127.0.0.0/8)
                            That's ok. easy to fix

                            But any way, the algorithm is quite straight forward

                            Seems you used quite a lot of Subs like MakeDWord
                            MakeSubMask etc. life don't need to be so complicated. ;)

                            And I also learned the sscanf as C++'s compromise of Regular Expressions. Haha, Thanks.

                            I will wait for other more simpler solutions..
      • You are the ONLY person here want to do something instead of saying 'Oh, simple' then hide... :D
        • i read what u say and tested some. you are right, it is not easy.
          i am trying use script, but not easy. it is seemed that it is not system admin job, more like programer. so script is not very easy for that. anyway, i will try.
          • scripts CAN do it, try try :)
            • by the way, for i am NT/2000 admin. so i am using VBScript not ShellScript.
    • Kixtart
    • this is too simple!
    • Could anyone give a script less than 25 lines to solve this simple question?? Come On Admins. GaoShou should show up now la...
    • IT人是不是“贱-不值钱”了一下啊,这种话题也有这么多人回复!
      • Take easy, take easy. Just for Fun, not for 贱. Heehee. If you are good, could you give a solution in SQL? Pls don't be so aggressive
        • Pay me $100, I will do a perfect application to you
    • My clumsy perl implementation ... all most no error checking ... with some effort you should be able to get it under 25 lines (currently ~40 lines).
      本文发表在 rolia.net 枫下论坛<pre>
      ===============
      #!/usr/bin/perl

      while (<>) {
      $low = limit(1, getipmask($_));
      $high = limit(0, getipmask($_));
      open(MYIPS,"./ips.txt") || die "open err\n";
      while (<MYIPS>) {
      if ($low >= limit(0, getipmask($_)) && $high <= limit(1, getipmask($_))) {
      print "Found: ", $_, "\n";
      }
      }
      close MYIPS;
      }

      sub limit {
      ($highlow, $mask, @octet) = @_;
      my $ip = 0;
      for ($i=0; $i<4; $i++) {
      $ip += $octet[$i]*256**(3-$i);
      }
      $ip = $ip & (2 ** 32 - 2 ** (32-$mask));
      if ($highlow == 1) {
      return $ip + 2 ** (32-$mask) - 1;
      } else {
      return $ip;
      }
      }

      sub getipmask {
      chomp;
      if ($_ =~ /\//) {
      ($myip, $mymask) = split (/\//, $_);
      } else {
      $myip = $_;
      $mymask = 32;
      }
      return($mymask, split (/\./, $myip));
      }
      ===============
      </pre>更多精彩文章及讨论,请光临枫下论坛 rolia.net
      • It is also good. but not better than 丑小鸭's. his/her algorithm is simpler and more efficient. Heehee. Is it a good exercise?
    • i did it in VbScript , but about 80 lines.But i can not put into 20 ines. i gave up.
    • Let me conclude the currently BEST algorithm
      1. Get ip and netmask from input
      if no NetMask then NetMask = 32

      2. ipnumber = ip1*16777216 + ip2 * 65536 + ip3 * 256 + ip4
      (this is 丑小鸭's MakeDWord and Denis2's FOR Loop )

      3. get InFileIPnumber and InFileMask from the file = 'ips.txt'
      using the same why above
      if InFileMask > NetMask then show "not found"
      (both of you two forgot this la. actually you don't need to calculate
      InFileMask > NetMask :)

      4. ipnumber = ipnumber / 2 ** ( 32 - InFileMask )
      inFileIPNumber = inFileIPNumber / 2 ** ( 32- InFileMask )
      if (ipnumber == ipFileIPNumber) then show "FOUND!"

      I think it is the simplest algorithm.
      So language is not important. The way to do it really is.

      Enjoy. :-)
      • 不要把简单复杂化。
        你这个东东grep一下就完了,还要算法吗?
        • PLEASE read the question carefully before you say something. DON'T be TOO confident... hehe
        • if you can grep it. You must be Grep Expert. ;-) . But obvious you are not...