一般做风控会对公司的外网IP加白,如果公司的分公司比较多,一般公司的网络工程师会把这些ip以CIDR的格式记录起来,

什么是CIDR的格式呢,比如:192.168.0.62/30

这里面 192.168.0.62代表的是主机地址 /30代表的是子网掩码

那根据192.168.0.62/30怎么取到实际的IP段呢?

 

①255.255.255.255       对应的是 =》          11111111.11111111.11111111.11111111
②那么 /30 代表       高32位全是1=》          11111111.11111111.11111111.11111100
③192.168.0.62            对应的是 =》           11000000.10101000.00000000.00111110

接下来 ②和③做与运算
11111111.11111111.11111111.11111100

11000000.10101000.00000000.00111110
等于
11000000.10101000.00000000.00111110 也就是192.168.0.62

 

!!注意看标黄色的,因为②的高32位都是1,也就是说ip段可以变的就是后面2位了

得出:

最小:11000000.10101000.00000000.00111100  也就是主机地址 192.168.0.60

最大:  11000000.10101000.00000000.00111111 也就是广播地址 192.168.0.63

得出结果可用的ip段为 >192.168.0.60 <192.168.0.63
也就是2个
192.168.0.61
192.168.0.62

 

那根据代码如何拿快速获取呢

 


class IPSegment
{
	private UInt32 _ip;
	private UInt32 _mask;
	private UInt32 _ip__;
	public IPSegment (string ipMask)
	{
		var arr = ipMask.Split ('/');
		_ip = arr [0].ParseIp();
		var mask = Int32.Parse(arr[1]);
		var mask1 = 32 - mask;
		if(mask1 <= 1){
			_ip__ = _ip;
		}
		var mask2 = new String('0',mask1);
		var mask3 = new String('1',8-mask1);
		var realMask = "255.255.255." + Convert.ToInt32(mask3+mask2, 2);
		_mask =realMask.ParseIp();
	}

	public IPSegment (string ip, string mask)
	{
		_ip = ip.ParseIp();
		_mask = mask.ParseIp();
	}
	public UInt32 NumberOfHosts { get { return ~_mask + 1; } }
	public UInt32 NetworkAddress { get { return _ip & _mask; } }
	public UInt32 BroadcastAddress { get { return NetworkAddress + ~_mask; } }
	public IEnumerable<UInt32> Hosts()
	{
		if (_ip__ != 0)
		{ 
            // 如果是32或者31的话则认为是自身
			yield return _ip__;
		}
		else
		{
			for (var host = NetworkAddress + 1; host < BroadcastAddress; host++)
			{
				yield return host;
			}
		}
		
	}
}
static class IpHelpers
{
	public static string ToIpString (this UInt32 value)
	{
		var bitmask = 0xff000000;
		var parts = new string [4];
		for (var i = 0; i < 4; i++)
		{
			var masked = (value & bitmask) >> ((3 - i) * 8);
			bitmask >>= 8;
			parts [i] = masked.ToString (CultureInfo.InvariantCulture);
		}
		return String.Join (".", parts);
	}
	public static UInt32 ParseIp (this string ipAddress)
	{
		var splitted = ipAddress.Split ('.');
		UInt32 ip = 0;
		for (var i = 0; i < 4; i++)
		{
			ip = (ip << 8) + UInt32.Parse (splitted [i]);
		}
		return ip;
	}
}

使用方式:

 

 

IPSegment ip = new IPSegment ("192.168.0.62/30");
Console.WriteLine (ip.NumberOfHosts);
Console.WriteLine (ip.NetworkAddress.ToIpString());
Console.WriteLine (ip.BroadcastAddress.ToIpString());
Console.WriteLine ("===");
foreach (UInt32 host in ip.Hosts())
{
	Console.WriteLine (IpHelpers.ToIpString (host));
}

或者这么用

 

IPSegment ip = new IPSegment ("192.168.0.62","255.255.255.252");
Console.WriteLine (ip.NumberOfHosts);
Console.WriteLine (ip.NetworkAddress.ToIpString());
Console.WriteLine (ip.BroadcastAddress.ToIpString());
Console.WriteLine ("===");
foreach (UInt32 host in ip.Hosts())
{
	Console.WriteLine (IpHelpers.ToIpString (host));
}

 

Enjoy!!!

关注公众号一起学习