1#[macro_use]
2extern crate lazy_static;
3
4use regex::Regex;
5use std::net::Ipv4Addr;
6
7#[derive(Debug)]
8struct IpMateData {
9 ip: u32,
10 sub_mark: u8,
11}
12
13#[derive(Debug)]
14pub struct IpPart {
15 ip: IpMateData,
16}
17
18lazy_static! {
19 static ref RE: Regex =
20 Regex::new(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,3})$").unwrap();
21}
22
23fn u32_to_ipv4(ip: u32) -> Ipv4Addr {
24 let mut u: [u8; 4] = [0; 4];
25
26 for i in 0..4 {
27 u[i] = ((ip >> (i * 8)) & 0xff) as u8;
28 }
29
30 Ipv4Addr::new(u[3], u[2], u[1], u[0])
31}
32
33impl IpPart {
34 pub fn new(ip: &str) -> Result<Self, String> {
41 if RE.is_match(ip) {
42 for cap in RE.captures_iter(ip) {
43 let nums: Vec<u8> = [&cap[1], &cap[2], &cap[3], &cap[4], &cap[5]]
44 .iter()
45 .map(|n| n.parse().unwrap())
46 .collect();
47
48 if nums[4] > 32 {
49 return Err(String::from("子网掩码不能大于32"));
50 }
51
52 let mut ip: u32 = (nums[0] as u32) << 24;
53 ip += (nums[1] as u32) << 16;
54 ip += (nums[2] as u32) << 8;
55 ip += nums[3] as u32;
56
57 ip = ip & !((1 << (32 - nums[4])) - 1);
58
59 return Ok(IpPart {
60 ip: IpMateData {
61 ip: ip,
62 sub_mark: nums[4],
63 },
64 });
65 }
66 }
67
68 Err(String::from("ip格式错误"))
69 }
70
71 pub fn size(&self) -> u32 {
73 1 << (32 - self.ip.sub_mark)
74 }
75
76 pub fn list(&self) -> Vec<Ipv4Addr> {
78 let mut list: Vec<Ipv4Addr> = Vec::new();
79
80 for i in 0..self.size() {
81 list.push(u32_to_ipv4(self.ip.ip + i));
82 }
83
84 list
85 }
86}
87
88#[test]
89fn test() {
90 let ip = IpPart::new("192.168.1.1/24").unwrap();
91
92 println!("{:?} size {}", ip.list(), ip.size());
93}