如果 IP 位于 IP 范围之间,则限制该 IP

发布于 2024-08-08 06:13:48 字数 703 浏览 10 评论 0原文

好的,今天是星期五下午,我度过了漫长的一周,所以希望得到一些帮助! 目前,我有一个 IP 范围列表,如下所示:

List<IPRange> ipRanges = new List<IPRange>();

ipRanges.Add(new IPRange { From = "145.36.0.0", To = "145.36.255.255" });
ipRanges.Add(new IPRange { From = "194.183.227.184", To = "194.183.227.191" });
ipRanges.Add(new IPRange { From = "193.131.192.0", To = "193.131.223.255" });

获取客户端的 IP 后,如果它落在这些范围集之间的任何位置,则需要将它们重定向到其他地方。

例如,

如果有人使用 IP 192.168.0.1 访问该网站,他们将被允许访问。 如果他们使用 145.36.1.0 进行访问,则不会允许他们访问,因为它位于该列表中的第一个范围之间。

我可以按周期分割每个 IP,并计算出范围开始变化的位置,然后进行比较,但这会对服务器造成沉重负担。

我知道 IP 基本上只是十进制数字,但我不太确定它是如何工作的。

以前有人遇到过这个吗?

干杯,肖恩。

Ok, it's friday afternoon, and i've had a long week so would appreciate some help!
Currently, i have a list of IP ranges, as follows:

List<IPRange> ipRanges = new List<IPRange>();

ipRanges.Add(new IPRange { From = "145.36.0.0", To = "145.36.255.255" });
ipRanges.Add(new IPRange { From = "194.183.227.184", To = "194.183.227.191" });
ipRanges.Add(new IPRange { From = "193.131.192.0", To = "193.131.223.255" });

After getting the IP of the client, if it falls anywhere between these sets of ranges, they need to be redirected elsewhere.

For example,

If someone visited the site with the IP 192.168.0.1, they would be allowed access.
If they visited with 145.36.1.0, they would not be allowed access because it falls between the first range in that list.

I could split each IP by the period, and work out where the range starts to change, then do a comparison, but that would be heavy on the server.

I know IP's are basically just decimal numbers, but am not really sure how that works.

Has anyone come across this before?

Cheers, Sean.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

寒冷纷飞旳雪 2024-08-15 06:13:48

将每个 IP 地址转换为数字,然后检查用户 ip 地址是否在这些数字之间。

public double Dot2LongIP(string DottedIP)
{
    int i;
    string [] arrDec;
    double num = 0;
    if (DottedIP == "")
    {
       return 0;
    }
    else
    {
       arrDec = DottedIP.Split('.');
       for(i = arrDec.Length - 1; i >= 0 ; i --)
       {
          num += ((int.Parse(arrDec[i])%256) * Math.Pow(256 ,(3 - i )));
       }
       return num;
    }
}

Convert Each IP-address to number, and then check if the user ip address is between those numbers.

public double Dot2LongIP(string DottedIP)
{
    int i;
    string [] arrDec;
    double num = 0;
    if (DottedIP == "")
    {
       return 0;
    }
    else
    {
       arrDec = DottedIP.Split('.');
       for(i = arrDec.Length - 1; i >= 0 ; i --)
       {
          num += ((int.Parse(arrDec[i])%256) * Math.Pow(256 ,(3 - i )));
       }
       return num;
    }
}
笔芯 2024-08-15 06:13:48

我会将 IP 地址转换为 32 位数字,然后执行简单的 >= From 和 <= 来检查它是否在范围内。

例如,192.168.1.1→ 192 * 256^3 + 168 * 256^2 + 1 * 256 + 1。

按照您的价值观工作,145.36.0.0 -> 2435055616 和 145.36.0.0 -> 2435121151。所以 145.36.200.30 -> 2435106846,并且落在该范围内,因此它是有效的。但是 145.35.255.255 -> 2435055615 不在范围内(只是勉强),因此失败。

I would convert the IP addresses to 32-bit numbers and then do a simple >= From and <= To check to see if it's in range.

For example, 192.168.1.1 -> 192 * 256^3 + 168 * 256^2 + 1 * 256 + 1.

Working with your values, 145.36.0.0 -> 2435055616 and 145.36.0.0 -> 2435121151. So 145.36.200.30 -> 2435106846, and falls in that range, so it's valid. But 145.35.255.255 -> 2435055615 is not in the range (just barely), so it fails.

樱娆 2024-08-15 06:13:48

我会编写我的 IPRange 类,以便 getter/setter 在内部将 IP 字符串转换为数字:

new IPRange { From = "145.36.0.0", To = "145.36.255.255" }

在内部设置:

int from = 145036000000;
int to = 145036255255;

然后添加一个 .IsInRange(string ip) 方法,将传入的 IP 转换为 name int 形式并进行简单的比较。

public bool IsInRange(string ipStr)
{
    int ip = ConvertIPStringToInt(ipStr);
    return (from <= ip && ip <= to);
}

这样,您就不必在每次检查时按句点分割范围内的 IP。

I would write my IPRange class so that the getter/setters internally convert the IP string to a number:

new IPRange { From = "145.36.0.0", To = "145.36.255.255" }

Would internally set:

int from = 145036000000;
int to = 145036255255;

Then add a .IsInRange(string ip) method that converts the incoming IP to the name int form and does a plain comparison.

public bool IsInRange(string ipStr)
{
    int ip = ConvertIPStringToInt(ipStr);
    return (from <= ip && ip <= to);
}

That way you dont have to split the IPs in the range by periods each time its checked.

您的好友蓝忘机已上羡 2024-08-15 06:13:48

只是为了好玩(以及某种程度的完整性) - 另一种明显的方法是确保在存储为字符串时,IP 地址的每个段始终使用 3 位数字,即 145.36.0.0 应该是 145.036.000.000 - 即这样字符串就可以直接比较。

不太明显的是拥有一个显式的 IP 地址类和一套您自己的比较逻辑(我鲁莽地假设 .NET 框架的深处还没有这样的东西......)

Just for fun (and some semblance of completeness) - the other way obvious to do this is to ensure that you always use 3 digits for each segment of the IP address when stored as a string i.e. 145.36.0.0 should be 145.036.000.000 - that way the strings would be directly comparable.

And the Less obvious would be to have an explicit IP Address class and a roll your own set of comparison logic (I'm rashly assuming that there isn't already something like this buried in the depths of the .NET framework...)

温柔戏命师 2024-08-15 06:13:48

几天前我读到了这篇文章。

您可以转换并比较您的 IP 范围。

IF exists (SELECT * from dbo.sysobjects 
    WHERE id = object_id(N'[dbo].[IsPrivateIP]') 
    AND OBJECTPROPERTY(id, N'IsScalarFunction') = 1)
DROP FUNCTION [dbo].[IsPrivateIP]
GO


CREATE FUNCTION dbo.IsPrivateIP( @vcIPAddress varchar(15))
/**************************************************************************
DESCRIPTION: Returns Numeric IP if not private, otherwise returns null

PARAMETERS:
        @vcIPAddress    - The string containing a valid IP

RETURNS:    IP converted to bigint or null if a private IP

USAGE:      SELECT dbo.IsPrivateIP( '207.158.26.10')

DEPENDANCIES:    dbo.IPStringToNumber() function    

AUTHOR: Karen Gayda

DATE:   06/11/2003

MODIFICATION HISTORY:
    WHO     DATE        DESCRIPTION
    ---     ----------  ---------------------------------------------------

***************************************************************************/

    RETURNS bigint
AS
BEGIN
    DECLARE @biClassALo bigint ,
        @biClassAHi bigint ,
        @biClassBLo bigint ,
        @biClassBHi bigint ,
        @biClassCLo bigint ,
        @biClassCHi bigint ,
        @biIP       bigint,
        @bTemp      int 

    SET @biClassALo = 167772160
    SET @biClassAHi = 169549375
    SET @biClassBLo = 2885681152
    SET @biClassBHi = 2887778303
    SET @biClassCLo = 3232235520
    SET @biClassCHi = 3232301055


    SET @biIP = dbo.IPStringToNumber(@vcIPAddress)
    IF @biIP BETWEEN @biClassALo AND @biClassAHi OR @biIP BETWEEN @biClassBLo AND @biClassBHi 
        OR @biIP BETWEEN @biClassCLo AND @biClassCHi 
        SET @biIP = NULL

    RETURN @biIP
END
GO

这是它需要的 IPStringToNumber 函数:

IF exists (SELECT * from dbo.sysobjects 
    WHERE id = object_id(N'[dbo].[IPStringToNumber]') 
    AND OBJECTPROPERTY(id, N'IsScalarFunction') = 1)
DROP FUNCTION [dbo].[IPStringToNumber]
GO

CREATE FUNCTION dbo.IPStringToNumber( @vcIPAddress varchar(15))
/**************************************************************************
DESCRIPTION: Returns Numeric IP, otherwise returns null

PARAMETERS:
        @vcIPAddress    - The string containing a valid IP

RETURNS:    IP converted to bigint or null if not a valid IP

USAGE:         SELECT  dbo.IPStringToNumber( '10.255.255.255')



AUTHOR: Karen Gayda

DATE:   06/11/2003

MODIFICATION HISTORY:
    WHO     DATE        DESCRIPTION
    ---     ----------  ---------------------------------------------------

***************************************************************************/

    RETURNS bigint
AS
BEGIN
    DECLARE 
        @biOctetA   bigint,
        @biOctetB   bigint,
        @biOctetC   bigint,
        @biOctetD   bigint,
        @biIP           bigint

    DECLARE @tblArray TABLE 
       (
        OctetID     smallint,       --Array index
        Octet       bigint          --Array element contents
       )

    --split the IP string and insert each octet into a table row
    INSERT INTO @tblArray
    SELECT ElementID, Convert(bigint,Element) FROM dbo.Split(@vcIPAddress, '.')

    --check that there are four octets and that they are within valid ranges
    IF (SELECT COUNT(*) FROM @tblArray WHERE Octet BETWEEN 0 AND 255) = 4
    BEGIN
        SET @biOctetA = (SELECT (Octet * 256 * 256 * 256) FROM @tblArray WHERE OctetID = 1)
        SET @biOctetB = (SELECT (Octet * 256 * 256 ) FROM @tblArray WHERE OctetID = 2)
        SET @biOctetC = (SELECT (Octet * 256 ) FROM @tblArray WHERE OctetID = 3)
        SET @biOctetD = (SELECT (Octet) FROM @tblArray WHERE OctetID = 4)
        SET @biIP = @biOctetA + @biOctetB + @biOctetC + @biOctetD
    END

    RETURN(@biIP)
END

参考资料:

http://www.sqlservercentral.com/脚本/Miscellaneous/31036/

http://www.sqlservercentral.com /作者/脚本/kgayda/17134/

I read about this a few days ago.

You can get your IP ranges converted and compare.

IF exists (SELECT * from dbo.sysobjects 
    WHERE id = object_id(N'[dbo].[IsPrivateIP]') 
    AND OBJECTPROPERTY(id, N'IsScalarFunction') = 1)
DROP FUNCTION [dbo].[IsPrivateIP]
GO


CREATE FUNCTION dbo.IsPrivateIP( @vcIPAddress varchar(15))
/**************************************************************************
DESCRIPTION: Returns Numeric IP if not private, otherwise returns null

PARAMETERS:
        @vcIPAddress    - The string containing a valid IP

RETURNS:    IP converted to bigint or null if a private IP

USAGE:      SELECT dbo.IsPrivateIP( '207.158.26.10')

DEPENDANCIES:    dbo.IPStringToNumber() function    

AUTHOR: Karen Gayda

DATE:   06/11/2003

MODIFICATION HISTORY:
    WHO     DATE        DESCRIPTION
    ---     ----------  ---------------------------------------------------

***************************************************************************/

    RETURNS bigint
AS
BEGIN
    DECLARE @biClassALo bigint ,
        @biClassAHi bigint ,
        @biClassBLo bigint ,
        @biClassBHi bigint ,
        @biClassCLo bigint ,
        @biClassCHi bigint ,
        @biIP       bigint,
        @bTemp      int 

    SET @biClassALo = 167772160
    SET @biClassAHi = 169549375
    SET @biClassBLo = 2885681152
    SET @biClassBHi = 2887778303
    SET @biClassCLo = 3232235520
    SET @biClassCHi = 3232301055


    SET @biIP = dbo.IPStringToNumber(@vcIPAddress)
    IF @biIP BETWEEN @biClassALo AND @biClassAHi OR @biIP BETWEEN @biClassBLo AND @biClassBHi 
        OR @biIP BETWEEN @biClassCLo AND @biClassCHi 
        SET @biIP = NULL

    RETURN @biIP
END
GO

Here is the IPStringToNumber function that it needs:

IF exists (SELECT * from dbo.sysobjects 
    WHERE id = object_id(N'[dbo].[IPStringToNumber]') 
    AND OBJECTPROPERTY(id, N'IsScalarFunction') = 1)
DROP FUNCTION [dbo].[IPStringToNumber]
GO

CREATE FUNCTION dbo.IPStringToNumber( @vcIPAddress varchar(15))
/**************************************************************************
DESCRIPTION: Returns Numeric IP, otherwise returns null

PARAMETERS:
        @vcIPAddress    - The string containing a valid IP

RETURNS:    IP converted to bigint or null if not a valid IP

USAGE:         SELECT  dbo.IPStringToNumber( '10.255.255.255')



AUTHOR: Karen Gayda

DATE:   06/11/2003

MODIFICATION HISTORY:
    WHO     DATE        DESCRIPTION
    ---     ----------  ---------------------------------------------------

***************************************************************************/

    RETURNS bigint
AS
BEGIN
    DECLARE 
        @biOctetA   bigint,
        @biOctetB   bigint,
        @biOctetC   bigint,
        @biOctetD   bigint,
        @biIP           bigint

    DECLARE @tblArray TABLE 
       (
        OctetID     smallint,       --Array index
        Octet       bigint          --Array element contents
       )

    --split the IP string and insert each octet into a table row
    INSERT INTO @tblArray
    SELECT ElementID, Convert(bigint,Element) FROM dbo.Split(@vcIPAddress, '.')

    --check that there are four octets and that they are within valid ranges
    IF (SELECT COUNT(*) FROM @tblArray WHERE Octet BETWEEN 0 AND 255) = 4
    BEGIN
        SET @biOctetA = (SELECT (Octet * 256 * 256 * 256) FROM @tblArray WHERE OctetID = 1)
        SET @biOctetB = (SELECT (Octet * 256 * 256 ) FROM @tblArray WHERE OctetID = 2)
        SET @biOctetC = (SELECT (Octet * 256 ) FROM @tblArray WHERE OctetID = 3)
        SET @biOctetD = (SELECT (Octet) FROM @tblArray WHERE OctetID = 4)
        SET @biIP = @biOctetA + @biOctetB + @biOctetC + @biOctetD
    END

    RETURN(@biIP)
END

References:

http://www.sqlservercentral.com/scripts/Miscellaneous/31036/

http://www.sqlservercentral.com/Authors/Scripts/kgayda/17134/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文