簡體   English   中英

如何檢查輸入 IP 是否在特定的 IP 范圍內

[英]How to check a input IP fall in a specific IP range

If we let users input a couple of ip ranges, eg, 172.16.11.5 - 100, how could I write a function to check if a IP (172.16.11.50) falls in the ranges?

.NET 中是否有任何現有的庫可供利用?

框架中沒有內置任何內容,但創建IPAddressRange類不會花費太多精力。

您可以通過在低地址、高地址和比較地址上調用IPAddress.GetAddressBytes來比較范圍。 從第一個字節開始,檢查比較地址是否在高/低地址范圍內。

此方法適用於 IPv4 和 IPv6 地址。

public class IPAddressRange
{
    readonly AddressFamily addressFamily;
    readonly byte[] lowerBytes;
    readonly byte[] upperBytes;

    public IPAddressRange(IPAddress lowerInclusive, IPAddress upperInclusive)
    {
        // Assert that lower.AddressFamily == upper.AddressFamily

        this.addressFamily = lowerInclusive.AddressFamily;
        this.lowerBytes = lowerInclusive.GetAddressBytes();
        this.upperBytes = upperInclusive.GetAddressBytes();
    }

    public bool IsInRange(IPAddress address)
    {
        if (address.AddressFamily != addressFamily)
        {
            return false;
        }

        byte[] addressBytes = address.GetAddressBytes();

        bool lowerBoundary = true, upperBoundary = true;

        for (int i = 0; i < this.lowerBytes.Length && 
            (lowerBoundary || upperBoundary); i++)
        {
            if ((lowerBoundary && addressBytes[i] < lowerBytes[i]) ||
                (upperBoundary && addressBytes[i] > upperBytes[i]))
            {
                return false;
            }

            lowerBoundary &= (addressBytes[i] == lowerBytes[i]);
            upperBoundary &= (addressBytes[i] == upperBytes[i]);
        }

        return true;
    }
}

注意:上面的代碼可以擴展為添加公共靜態工廠方法FromCidr(IPAddress address, int bits)

您可能需要考慮@jsakamoto 的這個庫,它允許您解析 IP 地址字符串的范圍,例如“192.168.0.0/24”和“192.168.0.0/255.255.255.0”和“192.168.0.0-192.168.0.255” , 並且可以包含檢查。 該庫支持 IPv4 和 IPv6。

https://github.com/jsakamoto/ipaddressrange

它也可以通過 NuGet 安裝:

http://www.nuget.org/packages/IPAddressRange/

using NetTools;
...
// rangeA.Begin is "192.168.0.0", and rangeA.End is "192.168.0.255".
var rangeA = IPAddressRange.Parse("192.168.0.0/255.255.255.0");
rangeA.Contains(IPAddress.Parse("192.168.0.34")); // is True.
rangeA.Contains(IPAddress.Parse("192.168.10.1")); // is False.
rangeA.ToCidrString(); // is 192.168.0.0/24

// rangeB.Begin is "192.168.0.10", and rangeB.End is "192.168.10.20".
var rangeB1 = IPAddressRange.Parse("192.168.0.10 - 192.168.10.20");
rangeB1.Contains(IPAddress.Parse("192.168.3.45")); // is True.
rangeB1.Contains(IPAddress.Parse("192.168.0.9")); // is False.

// Support shortcut range description. 
// ("192.168.10.10-20" means range of begin:192.168.10.10 to end:192.168.10.20.)
var rangeB2 = IPAddressRange.Parse("192.168.10.10-20");

// Support CIDR expression and IPv6.
var rangeC = IPAddressRange.Parse("fe80::/10"); 
rangeC.Contains(IPAddress.Parse("fe80::d503:4ee:3882:c586%3")); // is True.
rangeC.Contains(IPAddress.Parse("::1")); // is False.
public static bool IsInRange(string startIpAddr, string endIpAddr, string address)
{
    long ipStart = BitConverter.ToInt32(IPAddress.Parse(startIpAddr).GetAddressBytes().Reverse().ToArray(), 0);

    long ipEnd = BitConverter.ToInt32(IPAddress.Parse(endIpAddr).GetAddressBytes().Reverse().ToArray(), 0);

    long ip = BitConverter.ToInt32(IPAddress.Parse(address).GetAddressBytes().Reverse().ToArray(), 0);

    return ip >= ipStart && ip <= ipEnd; //edited
}

Console.WriteLine(IsInRange("100.0.0.1", "110.0.0.255", "102.0.0.4"));//true

最好的辦法是將這些地址轉換為整數,然后進行比較。

此處的示例: IP 到整數

要將 IP 地址轉換為整數,請將其分成四個八位字節。 例如,您提供的 ip 地址可以分解為:

First Octet:    217
Second Octet:   110
Third Octet:    18
Fourth Octet:   206

要從點分字符串計算十進制地址,請執行以下計算。

    (first octet * 256³) + (second octet * 256²) + (third octet * 256) + (fourth octet)
=   (first octet * 16777216) + (second octet * 65536) + (third octet * 256) + (fourth octet)
=   (217 * 16777216) + (110 * 65536) + (18 * 256) + (206)
=   3647869646

考慮到 IPv6,您也可以將它們轉換為整數(128 位與 32 位 IPv4)。 看看這個問題: Formatting IPv6 as an int in C# and storage it in SQL Server

最簡單的方法是讓框架為您執行此操作。 使用IPAddress.Parse解析地址,然后使用IPAddress.GetAddressBytes將“數字”作為byte[]獲取。

我之前在codeproject上使用過這段代碼,可能對你有用。

http://www.codeproject.com/KB/IP/ipnumbers.aspx

您可以向IPList添加由 From IP 和 To IP 號碼定義的 IP 號碼范圍。 該方法將范圍分解為標准 IP 范圍並找到它們的掩碼。 因此,“10.0.0.5”到“10.0.0.20”的范圍將被分解為以下范圍並添加到列表中:10.0.0.5、10.0.0.20、10.0.0.6/31、10.0.0.16/30 和 10.0。 0.8/29,您將有可能對此進行檢查。

免責聲明:該類僅使用簡單的數據集進行測試,並且該類缺乏對提供的 IP 編號和 IP 掩碼的驗證。 這應該在用於生產環境之前修復。

這里重新發布我的答案

不久前,我必須找到給定 IP 的位置。 我們從請求中獲得了 IP。 有免費的數據庫給了我們這個映射。 在 IPv4 中,當我們將 IP 稱為“abcd”時,它本質上是a * (256^3) + b * (256^2) + c * (256) + d

http://www.aboutmyip.com/AboutMyXApp/IP2Integer.jsp

所以當你說你想要一個以“a”開頭的IP地址時,你正在尋找a * 256^ 3和a * 256^3 + 256 * (256^2) (b = 256) + 256 *(256 ) (c=256) + 256( d=256) (下限/上限可能會有所不同,具體取決於您是否要包括/排除限制)。

也就是說,為特定目的保留了特定的 IP(例如 127.0.0.1 是 localhost,0.0.0.0 不能是 IP 等)。

所以你的 linq 查詢將是

from i in iList where i >= MIN && i <= MAX select i;

其中 iList 是您的初始列表 MIN 是您的范圍的最小值 MAX 是您的范圍的最大值

你能從你的 IP 范圍中找出子網掩碼嗎?

如果是這樣,那么也許你可以使用這個IsInSameSubnet方法..

我想 +1 BuddhiP 的回答,上面推薦 NuGet 的 IPAddressRange 包: https ://www.nuget.org/packages/IPAddressRange/

但是因為代碼格式在注釋中很難,我將在這里添加一個關於如何使用 IPAddressRange 的實用代碼示例。

CheckIPWhitelist 讀取名為 IPWhitelist 的設置,並假定 IPAddressRange 可以解析的 IP 范圍(例如“192.168.10.10-20;192.168.125.1-150;192.168.123.1-150”)的分號分隔列表。 該函數迭代范圍和意志,如果存在則返回 true,如果未找到則返回 false。

此函數是 VB.NET,並假定存在一些 ASP.NET 依賴項(例如 System.Web.HttpRequest 命名空間)

Imports NetTools ' ref. https://www.nuget.org/packages/IPAddressRange/

Function CheckIPWhitelist() As Boolean
    Dim match As Boolean = False
    Dim SourceIP As String = Request.UserHostAddress()

    ' Examples of valid IPWhitelist ranges 
    ' one range in longhand range format: "192.168.0.10 - 192.168.10.20"
    ' one range in shorthand range format: "192.168.10.10-20"
    ' multiple ranges separated by semicolons in shorthand range format: "192.168.10.10-20;192.168.125.1-150;192.168.123.1-150"
    Dim IPWhitelist As String = ConfigurationManager.AppSettings("IPWhitelist")

    Dim arrRanges As String() = IPWhitelist.Split(";")
    For i As Integer = 0 To arrRanges.Length - 1
        If arrRanges(i) IsNot Nothing Then
            Dim range As NetTools.IPAddressRange = IPAddressRange.Parse(arrRanges(i))
            If range.Contains(IPAddressRange.Parse(SourceIP)) = True Then
                match = True ' IP is in the whitelist, set a boolean
                Exit For
            End If
        End If
    Next
    Return match
End Function

您可以刪除它們中間的點並首先將所有 IP 轉換為 long,然后在 if 中檢查它們:

var givenIp = Convert.ToInt64(clientIp.Replace(".", ""));
var startIp = Convert.ToInt64(startRange.Replace(".", ""));
var endIp = Convert.ToInt64(endRange.Replace(".", ""));

if (givenIp != startIp && givenIp != endIp && (givenIp < startIp || givenIp > endIp))
{
   Console.WriteLine("your ip does not allow to access!");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM