4

好的,现在是星期五下午,我已经度过了漫长的一周,所以希望能得到一些帮助!目前,我有一个 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 基本上只是十进制数字,但我不确定它是如何工作的。

有没有人遇到过这个?

干杯,肖恩。

4

5 回答 5

7

将每个 IP-address 转换为 number,然后检查用户 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;
    }
}
于 2009-10-23T14:58:08.870 回答
7

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

例如,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 不在范围内(只是勉强),所以它失败了。

于 2009-10-23T14:59:21.677 回答
1

我会编写我的 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 转换为名称 int 形式并进行简单的比较。

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

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

于 2009-10-23T15:16:04.997 回答
1

只是为了好玩(和一些完整性的表象) - 另一种明显的方法是确保当存储为字符串时,IP 地址的每个段始终使用 3 位数字,即 145.36.0.0 应该是 145.036.000.000 - 那字符串可以直接比较的方式。

而不太明显的是有一个明确的 IP 地址类和一个你自己的比较逻辑集(我轻率地假设在 .NET 框架的深处还没有这样的东西......)

于 2009-10-23T15:26:19.640 回答
0

几天前我读到了这个。

您可以转换和比较您的 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/scripts/Miscellaneous/31036/

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

于 2009-10-23T15:00:35.277 回答