ip_part/
lib.rs

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    /// 创建IpPart
35    /// # Example
36    ///
37    /// ```rust
38    /// let ip = IpPart::new("192.168.1.0/24");
39    /// ```
40    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    /// 返回当前ip段的ip个数
72    pub fn size(&self) -> u32 {
73        1 << (32 - self.ip.sub_mark)
74    }
75
76    /// 返回当前ip段的所有ip
77    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}