none
關於IP比對的問題 RRS feed

  • 問題

  • 想請問,如果我有一個ip位址是 172.51.2.140
    資料庫裡有二個begin和end來範圍出網段
    我該如何寫,才能比對出,172.51.2.140是否在begin和end網段內?
    2010年1月15日 上午 02:35

解答

  • hi
    也可以這樣嘗試看看
    private void button1_Click( object sender, EventArgs e )
            {
                String startip = "172.51.2.1";
                String endip = "172.51.2.253";
                String currentip = "172.51.2.140";
                long startvalue = IP2Long( startip );
                long endvalue = IP2Long( endip );
                long currentvalue = IP2Long( currentip );
                if( currentvalue > startvalue && currentvalue < endvalue )
                    MessageBox.Show("範圍內");
            }

    public long IP2Long( String ip )
            {
                String[] ipBytes;
                double num = 0;
                if( !String.IsNullOrEmpty( ip ) )
                {
                    ipBytes = ip.Split( '.' );
                    for( Int32 i = ipBytes.Length - 1; i >= 0; i-- )
                    {
                        num += ( ( Int32.Parse( ipBytes[ i ] ) % 256 ) * Math.Pow( 256, ( 3 - i ) ) );
                    }
                }
                return ( long ) num;
            }
    http://www.dotblogs.com.tw/ricochen/Default.aspx
    • 已標示為解答 2010年1月15日 上午 04:01
    2010年1月15日 上午 03:00
  • tihs的網址是用IPAddress class來處理此問題,
    而若你的需求是希望直接給個IP由資料庫中取得所有符合此IP範圍的資料,用此方式必須將所有資料庫中的資料取出後一筆筆用程式的方式比對.

    如是上述問題,解決方式如下
    在儲存成資料庫前就必須轉換IP為一個數字
    IPv4此數字型態為long的數字而轉化方式為
    字串 "x1.x2.x3.x4"
    數值 x1*255^3 + x2*255^2 + X3*255 + X4

    所以儲存在資料庫的begin與end實際上就是兩個數字,後續要比對就簡單了
    只需將要比對的IP字串一樣先用上面方式轉換成數字
    然後於WHERE條件中用
    WHERE @ipnumber BETWEEN begin AND end
    這樣即可,並且可以解決效能上問題.

    PS:DateTime其實就是這種做法.


    • 已標示為解答 2010年1月15日 上午 08:01
    2010年1月15日 上午 03:09

所有回覆

  • HI,

    請參考:
    C# Snippet Tutorial - Comparing IP Addresses(http://www.switchonthecode.com/tutorials/csharp-snippet-tutorial-comparing-ip-addresses)
    2010年1月15日 上午 02:45
  • hi
    也可以這樣嘗試看看
    private void button1_Click( object sender, EventArgs e )
            {
                String startip = "172.51.2.1";
                String endip = "172.51.2.253";
                String currentip = "172.51.2.140";
                long startvalue = IP2Long( startip );
                long endvalue = IP2Long( endip );
                long currentvalue = IP2Long( currentip );
                if( currentvalue > startvalue && currentvalue < endvalue )
                    MessageBox.Show("範圍內");
            }

    public long IP2Long( String ip )
            {
                String[] ipBytes;
                double num = 0;
                if( !String.IsNullOrEmpty( ip ) )
                {
                    ipBytes = ip.Split( '.' );
                    for( Int32 i = ipBytes.Length - 1; i >= 0; i-- )
                    {
                        num += ( ( Int32.Parse( ipBytes[ i ] ) % 256 ) * Math.Pow( 256, ( 3 - i ) ) );
                    }
                }
                return ( long ) num;
            }
    http://www.dotblogs.com.tw/ricochen/Default.aspx
    • 已標示為解答 2010年1月15日 上午 04:01
    2010年1月15日 上午 03:00
  • tihs的網址是用IPAddress class來處理此問題,
    而若你的需求是希望直接給個IP由資料庫中取得所有符合此IP範圍的資料,用此方式必須將所有資料庫中的資料取出後一筆筆用程式的方式比對.

    如是上述問題,解決方式如下
    在儲存成資料庫前就必須轉換IP為一個數字
    IPv4此數字型態為long的數字而轉化方式為
    字串 "x1.x2.x3.x4"
    數值 x1*255^3 + x2*255^2 + X3*255 + X4

    所以儲存在資料庫的begin與end實際上就是兩個數字,後續要比對就簡單了
    只需將要比對的IP字串一樣先用上面方式轉換成數字
    然後於WHERE條件中用
    WHERE @ipnumber BETWEEN begin AND end
    這樣即可,並且可以解決效能上問題.

    PS:DateTime其實就是這種做法.


    • 已標示為解答 2010年1月15日 上午 08:01
    2010年1月15日 上午 03:09
  • 謝謝您,我已經試出來了
    2010年1月15日 上午 04:01
  • 資料庫已經建立起來了
    除非要再新增一欄把ip位址轉為數字寫語法insert進去
    而且新增資料的時候,也得在後台加上運算式,將ip位址轉為數字
    這樣就變的好複雜呢

    但我覺得這是一個好的建議
    將文字轉為數字的比對方式確實較為簡單
    我已經您的建議寫入我的NoteBook了
    下次在做鎖ip的網站時
    我會記得用您的方式來做ip比對的
    免得自找麻煩 Q_Q

    2010年1月15日 上午 04:06
  • 我的begin跟end的型態是nvarchar

    資料類似如下:
    ID  begin           End
     1  192.68.2.15  192.68.2.58
     2  192.68.3.15  192.68.3.58
     3  192.68.2.59  192.68.2.88

    T-SQL
    select * from testnet where '192.68.2.55' between begin and end

    查詢結果會出現ID=1,另兩筆並不會出現.
    2010年1月15日 上午 04:20
  • 那是因為你的資料剛好是如此,如果你的資料長度不同則可能會出錯譬如底下.
    192.68.2.59  192.68.2.88
    192.68.2.159  192.68.2.188

    2010年1月15日 上午 04:56
  • ^^" 看來只好轉數值才比較好比對了,用string還是有很多洞~
    2010年1月15日 上午 06:22
  • 那是因為你的資料剛好是如此,如果你的資料長度不同則可能會出錯譬如底下.
    192.68.2.59  192.68.2.88
    192.68.2.159  192.68.2.188


    果然string不能比大小......
    2010年1月15日 上午 08:03