use std::net::{TcpListener, UdpSocket};
use rand::Rng;
pub fn is_port_occupied(port: u16) -> bool {
let a =match TcpListener::bind(format!("0.0.0.0:{}", port)) {
Ok(_) => false,
Err(_) => true,
};
let b = match UdpSocket::bind(format!("0.0.0.0:{}", port)) {
Ok(_) => false,
Err(_) => true,
};
a || b
}
pub fn scan_occupied_ports() -> Vec<u16> {
let mut occupied = Vec::new();
for port in 1024..=65535 {
if is_port_occupied(port) {
occupied.push(port);
}
}
occupied
}
pub fn is_lucky(port: u16) -> bool {
let port_str = port.to_string();
port_str.contains('6') || port_str.contains('8') && !port_str.contains('4')
}
pub fn find_lucky_ports(count: usize) -> Vec<u16> {
let mut rng = rand::rng();
let occupied = scan_occupied_ports();
let mut lucky_ports = Vec::new();
while lucky_ports.len() < count {
let candidate = rng.random_range(1024..=65535);
if !occupied.contains(&candidate) && is_lucky(candidate) {
lucky_ports.push(candidate);
}
}
lucky_ports
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_is_lucky() {
assert!(is_lucky(68)); assert!(is_lucky(8888)); assert!(!is_lucky(44)); assert!(!is_lucky(123)); }
#[test]
fn test_is_port_occupied() {
assert!(is_port_occupied(80)); assert!(!is_port_occupied(54321)); }
}