1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
use std::cmp; const CPF_LENGTH: usize = 11; pub fn reserved_numbers() -> Vec<String> { vec![ String::from("00000000000"), String::from("11111111111"), String::from("22222222222"), String::from("33333333333"), String::from("44444444444"), String::from("55555555555"), String::from("66666666666"), String::from("77777777777"), String::from("88888888888"), String::from("99999999999"), ] } pub fn format(cpf: &str) -> String { let cpf = cpf.matches(char::is_numeric).collect::<Vec<_>>().concat(); if cpf.len() > 3 && cpf.len() <= 6 { format!("{}.{}", &cpf[0..3], &cpf[3..cpf.len()]) } else if cpf.len() >= 7 && cpf.len() <= 9 { format!("{}.{}.{}", &cpf[0..3], &cpf[3..6], &cpf[6..cpf.len()]) } else if cpf.len() >= 10 { let end_position = cmp::min(cpf.len(), CPF_LENGTH); format!( "{}.{}.{}-{}", &cpf[0..3], &cpf[3..6], &cpf[6..9], &cpf[9..end_position] ) } else { cpf } } pub fn is_valid(cpf: &str) -> bool { if cpf.matches(char::is_lowercase).count() > 0 || cpf.matches(char::is_uppercase).count() > 0 { return false; } let cpf = cpf.matches(char::is_numeric).collect::<Vec<_>>().concat(); let reserved_numbers = reserved_numbers(); !cpf.is_empty() && cpf.len() == CPF_LENGTH && !reserved_numbers.contains(&cpf) && validate(cpf) } fn validate(cpf: String) -> bool { let cpf = cpf.matches(char::is_numeric).collect::<Vec<_>>(); let sum = check_sum(&cpf, 10); let digit1: u32 = calc_digit(sum); let mut sum: u32 = check_sum(&cpf, 11); sum += digit1 * 2; let digit2: u32 = calc_digit(sum); cpf[9].parse::<u32>().unwrap() == digit1 && cpf[10].parse::<u32>().unwrap() == digit2 } fn check_sum(cpf: &[&str], factor: u32) -> u32 { let mut sum: u32 = 0; let mut factor: u32 = factor; for n in cpf.iter().take(9) { sum += n.parse::<u32>().unwrap() * factor; factor -= 1; } sum } fn calc_digit(sum: u32) -> u32 { let mod_sum1 = sum % 11; if mod_sum1 < 2 { 0 } else { 11 - mod_sum1 } }