LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C#設(shè)計(jì)IP地址屏蔽功能

admin
2022年6月11日 14:57 本文熱度 2062
出于安全考慮,幾乎每個(gè)動(dòng)態(tài)網(wǎng)站都具備IP地址屏蔽功能,而網(wǎng)上流傳的很多關(guān)于該功能的教程大都采用字符串保存和驗(yàn)證IP地址,我認(rèn)為這是不太科學(xué)的,我試圖找到最佳的設(shè)計(jì)方案。

    “IP地址的長度為32位,分為4段,每段8位,用十進(jìn)制數(shù)字表示,每段數(shù)字范圍為0~255,段與段之間用句點(diǎn)隔開。”

    由此我們了解到,IP地址實(shí)際上是一個(gè)32位正整數(shù),在C#中可以使用uint類型來表示,但SQLServer數(shù)據(jù)庫里好像沒有對(duì)應(yīng)的類型;轉(zhuǎn)而使用數(shù)據(jù)庫支持的int類型的話,則會(huì)出現(xiàn)溢出的情況;因此我們做出妥協(xié):使用long(bigint)類型。

TIP:

int取值范圍:-2,147,483,648 到 2,147,483,647

uint取值范圍:0 到 4,294,967,295

long取值范圍:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807

 

那么如何將IP地址轉(zhuǎn)為整數(shù)呢?我們看到IPAddress類中有一個(gè)“[否決的]”實(shí)例屬性Address,這個(gè)屬性的確可以返回一個(gè)long值,但是測(cè)試一下,得到的數(shù)據(jù)確實(shí)這樣的:

“127.0.0.1” -> 16777343

“127.0.0.2” –> 33554559

的確該讓它“否決”,這樣的整數(shù)對(duì)我們來說毫無意義,我們是無法通過這樣的方法比較傳入的IP是否介于兩個(gè)IP值之間的。

那么只有自己動(dòng)手了,我們將通過IPAddress類的GetAddressBytes()實(shí)例方法獲取IP的4個(gè)段的值,然后將它們組合為一個(gè)整數(shù),下面將提供這個(gè)擴(kuò)展方法:

/// <summary>

/// IP地址轉(zhuǎn)為整數(shù)形式

/// </summary>

/// <returns>整數(shù)</returns>

public static long 轉(zhuǎn)換為整數(shù)(this IPAddress ip)

{

    int x = 3;

    long o = 0;

    foreach (byte f in ip.GetAddressBytes())

    {

        o += (long)f << 8 * x--;

    }

    return o;

}

你可以這樣使用這個(gè)擴(kuò)展方法:

IPAddress.Parse("127.0.0.1").轉(zhuǎn)換為整數(shù)()

這里還有一個(gè)用于逆轉(zhuǎn)換的擴(kuò)展方法,

用于將long轉(zhuǎn)回IPAddress:

/// <summary>

/// 將整數(shù)轉(zhuǎn)為IP地址

/// </summary>

/// <returns>IP地址</returns>

public static IPAddress 轉(zhuǎn)換為IP地址(this long l)

{

    var b = new byte[4];

    for (int i = 0; i < 4; i++)

    {

        b[3 - i] = (byte)(l >> 8 * i & 255);

    }

    return new IPAddress(b);

}

這樣我們就可以通過計(jì)算得到正確并有意義的整數(shù)了:

127.0.0.1 -> 2130706433

127.0.0.2 –> 2130706434

OK,確立了方案核心,下面開始設(shè)計(jì)SQLServer數(shù)據(jù)表。這樣設(shè)計(jì)后,在添加時(shí)將起始和終止IP地址轉(zhuǎn)為long類型并存入,并指定一個(gè)過期時(shí)間。

在驗(yàn)證時(shí)只需要獲取所有未過期的條目,比較傳入的IP地址是否介于起始值和終止值之間即可。

以往通過字符串存儲(chǔ)和驗(yàn)證的方案中,屏蔽時(shí)要么屏蔽一個(gè)精確的IP地址,要么就屏蔽一段或兩段IP,如“192.168.*.*”,要想屏蔽“192.168.1.200”到“192.168.4.64”之間的IP的話,將會(huì)非常麻煩;

而我們這樣設(shè)計(jì)就可以輕松實(shí)現(xiàn):“192.168.1.200”在數(shù)據(jù)庫里存儲(chǔ)的是“3232235976”,“192.168.4.64”在數(shù)據(jù)庫中是“3232236608”,即使使用肉眼也能極快地判斷傳入的地址是否介于它們之間,更不要說計(jì)算機(jī)查詢了。

添加IP屏蔽記錄的代碼:

/// <summary>

/// 添加一個(gè)新的IP屏蔽區(qū)段

/// </summary>

/// <param name="IP區(qū)段起始值">起始IP,如61.51.200.0</param>

/// <param name="IP區(qū)段終止值">終止IP,如61.51.255.255</param>

/// <param name="過期時(shí)間">屏蔽截止時(shí)間</param>

/// <returns>ID號(hào)</returns>

public static Guid 添加(string IP區(qū)段起始值string IP區(qū)段終止值DateTime 過期時(shí)間)

{

    var id = Guid.NewGuid();

    var sip = IPAddress.Parse(IP區(qū)段起始值).轉(zhuǎn)換為整數(shù)();

    var eip = IPAddress.Parse(IP區(qū)段終止值).轉(zhuǎn)換為整數(shù)();

    using (var c = new SiteMainEntities())

    {

        //檢測(cè)是否已存在相同的IP屏蔽記錄

        var a = c.IP地址屏蔽.where(f => f.區(qū)段起始值 == sip && f.區(qū)段終止值 == eip);

        //如果存在則更新其過期時(shí)間

        if (a.Count()>0)

        {

            var l = a.First();

            if (l.過期時(shí)間 過期時(shí)間) l.過期時(shí)間 過期時(shí)間;

        }

        //不存在則正常添加一個(gè)新的屏蔽記錄

        else c.AddToIP地址屏蔽(new IP地址屏蔽 { ID = id, 過期時(shí)間 過期時(shí)間區(qū)段起始值 = sip, 區(qū)段終止值 = eip });

        c.SaveChanges();

    }

    return id;

}


檢測(cè)指定IP地址是否被屏蔽的代碼:

/// <summary>

/// 檢測(cè)指定IP地址是否已受到屏蔽

/// </summary>

/// <param name="IP地址">要檢測(cè)的IP地址</param>

/// <returns>是否屬于已屏蔽的IP</returns>

public static bool 檢測(cè)是否被屏蔽(string IP地址)

{

    var ip = IPAddress.Parse(IP地址).轉(zhuǎn)換為整數(shù)();

    using (var c = new SiteMainEntities())

    {

        return c.IP地址屏蔽.Count(f => f.過期時(shí)間 DateTime.Now && ip >= f.區(qū)段起始值 && ip <= f.區(qū)段終止值0;

    }

}

    這種方案比起以往的字符串驗(yàn)證方案來說優(yōu)雅了許多,并可以提高數(shù)據(jù)庫查詢的效率,建議各位在日后的網(wǎng)站開發(fā)中都采用此方案。


該文章在 2022/6/11 14:57:06 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
午夜影院福利免费在线看 | 天天躁久久躁中文字字幕 | 天天看片在线视频播放 | 亚洲天堂一区二区中文字幕 | 天堂在线做性视频 | 在线观看欧美国产 |