pub fn validate_credit_card(num: &str) -> bool {
luhn(num)
}
fn luhn(num: &str) -> bool {
let digits: Vec<u32> = num.chars().filter_map(|c| c.to_digit(10)).collect();
if digits.is_empty() {
return false;
}
let mut sum = 0u32;
let mut dbl = false;
for d in digits.iter().rev() {
let mut v = *d;
if dbl {
v *= 2;
if v > 9 {
v -= 9;
}
}
sum += v;
dbl = !dbl;
}
sum % 10 == 0
}
pub fn validate_iban(iban: &str) -> bool {
let mut s: String = iban.chars().filter(|c| !c.is_whitespace()).collect();
s.make_ascii_uppercase();
if s.len() < 15 || s.len() > 34 || !s.chars().all(|c| c.is_ascii_alphanumeric()) {
return false;
}
let rearranged = format!("{}{}", &s[4..], &s[..4]);
let mut rem: u32 = 0;
for ch in rearranged.chars() {
let mapped = if ch.is_ascii_alphabetic() {
((ch as u8 - b'A') as u32 + 10).to_string()
} else {
ch.to_string()
};
for d in mapped.bytes() {
let digit = (d - b'0') as u32;
rem = (rem * 10 + digit) % 97;
}
}
rem == 1
}
pub fn validate_phone(phone: &str) -> bool {
let mut chars = phone.chars();
match chars.next() {
Some('+') => {}
_ => return false,
}
let digits: String = chars.collect();
if digits.is_empty() || digits.len() > 15 {
return false;
}
let mut iter = digits.chars();
match iter.next() {
Some(c) if c.is_ascii_digit() && c != '0' => {}
_ => return false,
}
if !iter.all(|c| c.is_ascii_digit()) {
return false;
}
true
}
pub fn validate_ssn(ssn: &str) -> bool {
let digits: String = ssn.chars().filter(|c| c.is_ascii_digit()).collect();
if digits.len() != 9 {
return false;
}
let area: u32 = digits[0..3].parse().unwrap_or(0);
let group: u32 = digits[3..5].parse().unwrap_or(0);
let serial: u32 = digits[5..9].parse().unwrap_or(0);
if area == 0 || area == 666 || (900..=999).contains(&area) {
return false;
}
if group == 0 || serial == 0 {
return false;
}
true
}
pub fn is_ascii(s: &str) -> bool {
s.is_ascii()
}
pub fn is_utf8(bytes: &[u8]) -> bool {
std::str::from_utf8(bytes).is_ok()
}