dataforge/generators/
internet.rs1use rand::seq::SliceRandom;
4use rand::Rng;
5
6const EMAIL_DOMAINS: &[&str] = &[
8 "gmail.com", "yahoo.com", "hotmail.com", "outlook.com", "qq.com",
9 "163.com", "126.com", "sina.com", "sohu.com", "example.com"
10];
11
12const TLDS: &[&str] = &[
14 "com", "org", "net", "edu", "gov", "mil", "int", "cn", "uk", "de", "fr", "jp"
15];
16
17const USER_AGENTS: &[&str] = &[
19 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
20 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
21 "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36"
22];
23
24pub fn email() -> String {
26 let mut rng = rand::thread_rng();
27 let username_len = rng.gen_range(5..=15);
28 let username: String = (0..username_len)
29 .map(|_| {
30 let chars = b"abcdefghijklmnopqrstuvwxyz0123456789";
31 chars[rng.gen_range(0..chars.len())] as char
32 })
33 .collect();
34
35 let domain = EMAIL_DOMAINS.choose(&mut rng).unwrap();
36 format!("{}@{}", username, domain)
37}
38
39pub fn username() -> String {
41 let mut rng = rand::thread_rng();
42 let len = rng.gen_range(6..=20);
43 (0..len)
44 .map(|_| {
45 let chars = b"abcdefghijklmnopqrstuvwxyz0123456789_";
46 chars[rng.gen_range(0..chars.len())] as char
47 })
48 .collect()
49}
50
51pub fn password(length: usize) -> String {
53 let mut rng = rand::thread_rng();
54 let chars = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";
55 (0..length)
56 .map(|_| chars[rng.gen_range(0..chars.len())] as char)
57 .collect()
58}
59
60pub fn strong_password() -> String {
62 let mut rng = rand::thread_rng();
63 let length = rng.gen_range(12..=20);
64
65 let mut password = String::new();
66
67 password.push(('A'..='Z').nth(rng.gen_range(0..26)).unwrap());
69
70 password.push(('a'..='z').nth(rng.gen_range(0..26)).unwrap());
72
73 password.push(('0'..='9').nth(rng.gen_range(0..10)).unwrap());
75
76 let special_chars = "!@#$%^&*";
78 password.push(special_chars.chars().nth(rng.gen_range(0..special_chars.len())).unwrap());
79
80 let all_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*";
82 for _ in 4..length {
83 password.push(all_chars.chars().nth(rng.gen_range(0..all_chars.len())).unwrap());
84 }
85
86 let mut chars: Vec<char> = password.chars().collect();
88 chars.shuffle(&mut rng);
89 chars.into_iter().collect()
90}
91
92pub fn domain() -> String {
94 let mut rng = rand::thread_rng();
95 let name_len = rng.gen_range(5..=15);
96 let name: String = (0..name_len)
97 .map(|_| {
98 let chars = b"abcdefghijklmnopqrstuvwxyz";
99 chars[rng.gen_range(0..chars.len())] as char
100 })
101 .collect();
102
103 let tld = TLDS.choose(&mut rng).unwrap();
104 format!("{}.{}", name, tld)
105}
106
107pub fn url() -> String {
109 let mut rng = rand::thread_rng();
110 let protocols = ["http", "https"];
111 let protocol = protocols.choose(&mut rng).unwrap();
112 let domain = domain();
113 let path_len = rng.gen_range(0..=3);
114
115 let mut url = format!("{}://{}", protocol, domain);
116
117 for _ in 0..path_len {
118 let segment_len = rng.gen_range(3..=10);
119 let segment: String = (0..segment_len)
120 .map(|_| {
121 let chars = b"abcdefghijklmnopqrstuvwxyz0123456789";
122 chars[rng.gen_range(0..chars.len())] as char
123 })
124 .collect();
125 url.push('/');
126 url.push_str(&segment);
127 }
128
129 url
130}
131
132pub fn ip_address() -> String {
134 let mut rng = rand::thread_rng();
135 format!(
136 "{}.{}.{}.{}",
137 rng.gen_range(1..=255),
138 rng.gen_range(0..=255),
139 rng.gen_range(0..=255),
140 rng.gen_range(1..=254)
141 )
142}
143
144pub fn ipv6_address() -> String {
146 let mut rng = rand::thread_rng();
147 (0..8)
148 .map(|_| format!("{:04x}", rng.gen_range(0..=0xffff)))
149 .collect::<Vec<_>>()
150 .join(":")
151}
152
153pub fn mac_address() -> String {
155 let mut rng = rand::thread_rng();
156 (0..6)
157 .map(|_| format!("{:02x}", rng.gen_range(0..=255)))
158 .collect::<Vec<_>>()
159 .join(":")
160}
161
162pub fn ipv4() -> String {
164 ip_address()
165}
166
167pub fn ipv6() -> String {
169 ipv6_address()
170}
171
172pub fn default_password() -> String {
174 password(12)
175}
176
177pub fn user_agent() -> String {
179 let mut rng = rand::thread_rng();
180 USER_AGENTS.choose(&mut rng).unwrap().to_string()
181}
182
183pub fn port() -> u16 {
185 let mut rng = rand::thread_rng();
186 rng.gen_range(1024..=65535)
187}
188
189#[cfg(test)]
190mod tests {
191 use super::*;
192
193 #[test]
194 fn test_email() {
195 let email = email();
196 assert!(email.contains('@'));
197 assert!(email.contains('.'));
198 }
199
200 #[test]
201 fn test_strong_password() {
202 let password = strong_password();
203 assert!(password.len() >= 12);
204 assert!(password.chars().any(|c| c.is_uppercase()));
205 assert!(password.chars().any(|c| c.is_lowercase()));
206 assert!(password.chars().any(|c| c.is_ascii_digit()));
207 assert!(password.chars().any(|c| "!@#$%^&*".contains(c)));
208 }
209
210 #[test]
211 fn test_ip_address() {
212 let ip = ip_address();
213 let parts: Vec<&str> = ip.split('.').collect();
214 assert_eq!(parts.len(), 4);
215
216 for part in parts {
217 let num: u16 = part.parse().unwrap();
218 assert!(num <= 255);
219 }
220 }
221
222 #[test]
223 fn test_mac_address() {
224 let mac = mac_address();
225 let parts: Vec<&str> = mac.split(':').collect();
226 assert_eq!(parts.len(), 6);
227
228 for part in parts {
229 assert_eq!(part.len(), 2);
230 assert!(u8::from_str_radix(part, 16).is_ok());
231 }
232 }
233}