如何用C#验证IP是否为局域网地址
前一阵子有【广州.NET群】的客户问起这个问题,说他们需要验证客户输入的网站是否为局域网。其实局域网的IP并没有确定的定义,只要是局域网中,即可设置为任何一个IP。
但确实存在一个内网保留地址的定义,它会确保公网IPv4的地址不会分配在“内网保留地址”中,该地址定义如下:
10.0.0.0/8,即10.0.0.0-10.255.255.255;
172.16.0.0/12,即172.16.0.0-172.31.255.255;
192.168.0.0/16,即192.168.0.0-192.168.255.255。
客户澄清,他确实就是想验证IPv4字符串是否为内网保留地址。
下面我们来想想几种验证IPv4地址字符串是否为内网保留地址的方法。
首先写出该方法的签名:
bool IsPrivateNetwork(string ipv4Address) { }
然后构建测试数据,显示期待结果:
var testData = new Dictionary<string, bool> { [""] = false, ["Not A IP"] = false, ["225.5.5.5"] = false, ["175.10.74.64"] = false, ["192.168.1.13"] = true, ["10.10.24.220"] = true, ["172.24.1.120"] = true, ["172.32.1.120"] = false, }; string output = String.Join("\r\n", testData.Select(x => $"[{x.Key,12}] Expected: {x.Value,5},\tActual: {IsPrivateNetwork(x.Key),5}")); Console.WriteLine(output);
方法1——StartsWith()
这是最容易想到的方法,用字符串的Substring、StartsWith等方式来实现:
bool IsPrivateNetwork(string ipv4Address) { if (IPAddress.TryParse(ipv4Address, out _)) { if (ipv4Address.StartsWith("192.168.") || ipv4Address.StartsWith("10.")) { return true; } if (ipv4Address.StartsWith("172.")) { string seg2 = ipv4Address[4..7]; if (seg2.EndsWith('.') && String.Compare(seg2, "16.") >= 0 && String.Compare(seg2, "31.") <= 0) { return true; } } } return false; }
注意这种方式在验证A类网站和C类网站时都非常简单(确实约大多数客户都会用这两种)。B类网络是个特例,让这个代码稍复杂化了,需要多对几个字符串进行判断——导致代码比较复杂。
输入结果如下:
[ ] Expected: False, Actual: False
[ Not A IP] Expected: False, Actual: False
[ 225.5.5.5] Expected: False, Actual: False
[175.10.74.64] Expected: False, Actual: False
[192.168.1.13] Expected: True, Actual: True
[10.10.24.220] Expected: True, Actual: True
[172.24.1.120] Expected: True, Actual: True
[172.32.1.120] Expected: False, Actual: False
我觉得这种方法……还挺不错,关键都是很直白的API调用,浅显易懂,如果我是技术负责人,我多半是允许员工写这种方式的。
另外如果追求“函数式”,可能可以写成这个样子,实现“一行代码”搞定(效果一样):
bool IsPrivateNetwork2(string ipv4Address) => IPAddress.TryParse(ipv4Address, out _) && ( ipv4Address.StartsWith("192.168.") || ipv4Address.StartsWith("10.") || ipv4Address.StartsWith("172.") && ipv4Address[6] == '.' && int.Parse(ipv4Address[4..6]) switch { var x when x >= 16 && x <= 31 => true, _ => false } );
方法2——使用IPAddress
.NET是个宝库,除了可以使用IPAddress类辅助做验证,实现起来会简单许多:
bool IsPrivateNetwork3(string ipv4Address) { if (IPAddress.TryParse(ipv4Address, out var ip)) { byte[] ipBytes = ip.GetAddressBytes(); if (ipBytes[0] == 10) return true; if (ipBytes[0] == 172 && ipBytes[1] >= 16 && ipBytes[1] <= 31) return true; if (ipBytes[0] == 192 && ipBytes[1] == 168) return true; } return false; }
该方式的关键是借助IPAddress类的GetAddressBytes()方法,即可非常轻松地完全这个验证——同时代码更简单。
如果追求“函数式”编程,“一行”代码的版本如下(效果相同):
bool IsPrivateNetwork(string ipv4Address) => IPAddress.TryParse(ipv4Address, out var ip) && ip.GetAddressBytes() switch { var x when x[0] == 10 => true, var x when x[0] == 172 && x[1] >= 16 && x[1] <= 31 => true, var x when x[0] == 192 && x[1] == 168 => true, _ => false };
方法3——使用正则表达式
这种挺麻烦的,但也没什么好说的,直接上代码:
bool IsPrivateNetwork(string ipv4Address) => Regex.IsMatch(input, @"(^192\.168\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)|(^172\.([1][6-9]|[2][0-9]|[3][0-1])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)|(^10\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])\.([0-9]|[0-9][0-9]|[0-2][0-5][0-5])$)", RegexOptions.None);
这才是真一行代码搞定😂
不开玩笑,正则表达式性能其实差很多,比以上两种方式差得远——最关键的是,我把这正则表达式写出来,就再也不想维护了😂
总结
俗话说“条条道路通罗马”,完成一件简单的任务可能会存在不同的办法,但办法与办法之间还是有较大的区别,我觉得重点的是要多写,多比较,多体会。
以上就是如何用C#验证IP是否为局域网地址的详细内容,更多关于C#验证IP是否为局域网的资料请关注猪先飞其它相关文章!
相关文章
- 我们在使用C#做项目的时候,基本上都需要制作登录界面,那么今天我们就来一步步看看,如果简单的实现登录界面呢,本文给出2个例子,由简入难,希望大家能够喜欢。...2020-06-25
- 这篇文章主要介绍了C# 字段和属性的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-11-03
- 这篇文章主要介绍了C#中截取字符串的的基本方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-03
- 本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
- 这篇文章主要介绍了C#实现简单的Http请求的方法,以实例形式较为详细的分析了C#实现Http请求的具体方法,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C#中new的几种用法,具有很好的参考价值,下面跟着小编一起来看下吧...2020-06-25
使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)
这篇文章主要介绍了使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25- 这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
- 这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
- 在昨天的《Javascript权威指南》学习笔记之十:ECMAScript 5 增强的对象模型一文中,对于一段代码的调试出现了一个奇怪现象,现将源代码贴在下面: 复制代码 代码如下: <script type="text/javascript"> function Person(){}...2014-05-31
- 最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
- 这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25
- 本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
- 轻松学习C#的基础入门,了解C#最基本的知识点,C#是一种简洁的,类型安全的一种完全面向对象的开发语言,是Microsoft专门基于.NET Framework平台开发的而量身定做的高级程序设计语言,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C#变量命名规则小结,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-09
- 这篇文章主要介绍了c#中(&&,||)与(&,|)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 这篇文章主要介绍了C#绘制曲线图的方法,以完整实例形式较为详细的分析了C#进行曲线绘制的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
- 本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
- 这篇文章主要介绍了c#自带缓存使用方法,包括获取数据缓存、设置数据缓存、移除指定数据缓存等方法,需要的朋友可以参考下...2020-06-25
- 复制代码 代码如下: //element:需要添加新样式的元素,value:新的样式 function addClass(element, value ){ if (!element.className){ element.className = value; }else { newClassName = element.className; newClas...2014-05-31