Skip to content

Commit

Permalink
Merge pull request #16 from petcompufc/dev
Browse files Browse the repository at this point in the history
Improve CPF validation
  • Loading branch information
thewillyan committed May 16, 2023
2 parents ec18b54 + ae01d73 commit bb10631
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 33 deletions.
70 changes: 48 additions & 22 deletions src/cert/csv_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,31 +176,57 @@ impl Cpf {
pub fn new(value: String) -> Result<Self, ParseError<String>> {
let value = value.trim();
let err = Err(ParseError::new(
"Valid CPF of the form 000.000.000-00",
"Valid CPF",
value.to_owned(),
));

for (i, part) in value.split('.').enumerate() {
if i == 2 {
let (left, right) = match part.split_once('-') {
Some(v) => v,
None => return err,
};
let (nums, digit) = match value.split_once('-') {
Some(vals) => vals,
None => return err,
};

if left.len() != 3 || left.parse::<u64>().is_err() {
return err;
}
if digit.len() != 2 {
return err;
}

if right.len() != 2 || right.parse::<u16>().is_err() {
return err;
}
} else if part.len() != 3 && part.parse::<u16>().is_err() {
let mut nums_arr = [0; 9];
let mut i = 0;
for part in nums.split('.') {
if part.len() != 3 {
return err;
}

for c in part.chars() {
match c.to_digit(10) {
Some(n) => {
nums_arr[i] = n as u16
},
None => return err
}
i += 1;
}
}
Ok(Self {
id: value.to_owned(),
})

let expected_digit = Self::gen_digit(nums_arr);
match digit.parse::<u8>() {
Ok(n) if n == expected_digit => Ok(Self {
id: value.to_owned(),
}),
_ => err,
}
}

fn gen_digit(nums: [u16; 9]) -> u8 {
let mut sum = 0;
for i in 0..9 {
sum += nums[i as usize] * (10 - i);
}
let j = if sum % 11 <= 1 { 0 } else { 11 - (sum % 11) };

sum += nums.iter().sum::<u16>() + (2 * j);
let k = if sum % 11 <= 1 { 0 } else { 11 - (sum % 11) };

(j * 10 + k) as u8
}

pub fn as_str(&self) -> &str {
Expand Down Expand Up @@ -271,13 +297,13 @@ mod tests {

#[test]
fn check_att_cpf() {
assert!(Cpf::new("08911684350".to_owned()).is_err());
assert!(Cpf::new("089.116.843.50".to_owned()).is_err());
assert!(Cpf::new("68116578553".to_owned()).is_err());
assert!(Cpf::new("633.834.740.89".to_owned()).is_err());

let cpf1 = Cpf::new("089.116.843-50".to_owned()).expect("it should be a valid CPF");
assert_eq!("089.116.843-50", cpf1.as_str());
let cpf1 = Cpf::new("762.050.858-95".to_owned()).expect("it should be a valid CPF");
assert_eq!("762.050.858-95", cpf1.as_str());

let cpf2 = Cpf::new(" 089.116.843-50 ".to_owned()).expect("it should be a valid CPF");
let cpf2 = Cpf::new(" 762.050.858-95 ".to_owned()).expect("it should be a valid CPF");
assert_eq!(cpf1, cpf2);
}
}
22 changes: 11 additions & 11 deletions src/cert/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,17 @@ mod tests {
fn atts_to_sql() {
let att_a = Attendee {
name: "A".to_owned(),
cpf: Cpf::new("000.000.000-00".to_owned()).expect("valid cpf"),
cpf: Cpf::new("207.062.844-29".to_owned()).expect("valid cpf"),
workload: 1,
};
let att_b = Attendee {
name: "B".to_owned(),
cpf: Cpf::new("111.111.111-11".to_owned()).expect("valid cpf"),
cpf: Cpf::new("647.748.630-09".to_owned()).expect("valid cpf"),
workload: 1,
};
let pool = vec![att_a, att_b].to_sql();

let vals = "('A', '000.000.000-00'),('B', '111.111.111-11')";
let vals = "('A', '207.062.844-29'),('B', '647.748.630-09')";
let result = format!("INSERT IGNORE INTO usuario (nome, identificacao) VALUES {vals};\n");

assert_eq!(result, pool.to_string());
Expand All @@ -145,12 +145,12 @@ mod tests {
};
let att_a = Attendee {
name: "A".to_owned(),
cpf: Cpf::new("000.000.000-00".to_owned()).expect("valid cpf"),
cpf: Cpf::new("754.751.875-33".to_owned()).expect("valid cpf"),
workload: 1,
};
let att_b = Attendee {
name: "B".to_owned(),
cpf: Cpf::new("111.111.111-11".to_owned()).expect("valid cpf"),
cpf: Cpf::new("647.748.630-09".to_owned()).expect("valid cpf"),
workload: 2,
};
let atts = vec![att_a, att_b];
Expand All @@ -163,8 +163,8 @@ mod tests {
&[
"INSERT IGNORE INTO texto (texto) VALUES ('Some description')",
"SET @txtid := (SELECT id FROM texto WHERE texto='Some description')",
"SET @uid0 := (SELECT id FROM usuario WHERE identificacao='000.000.000-00')",
"SET @uid1 := (SELECT id FROM usuario WHERE identificacao='111.111.111-11')",
"SET @uid0 := (SELECT id FROM usuario WHERE identificacao='754.751.875-33')",
"SET @uid1 := (SELECT id FROM usuario WHERE identificacao='647.748.630-09')",
"INSERT INTO participacao (usuario, evento, texto, ch) \
VALUES (@uid0, @evid, @txtid, 1),(@uid1, @evid, @txtid, 2);\n",
]
Expand All @@ -183,12 +183,12 @@ mod tests {
};
let att_a = Attendee {
name: "A".to_owned(),
cpf: Cpf::new("000.000.000-00".to_owned()).expect("valid cpf"),
cpf: Cpf::new("754.751.875-33".to_owned()).expect("valid cpf"),
workload: 1,
};
let att_b = Attendee {
name: "B".to_owned(),
cpf: Cpf::new("111.111.111-11".to_owned()).expect("valid cpf"),
cpf: Cpf::new("647.748.630-09".to_owned()).expect("valid cpf"),
workload: 2,
};
let event = data.into_event(vec![att_a, att_b]);
Expand All @@ -207,12 +207,12 @@ mod tests {
};
let att_a = Attendee {
name: "A".to_owned(),
cpf: Cpf::new("000.000.000-00".to_owned()).expect("valid cpf"),
cpf: Cpf::new("754.751.875-33".to_owned()).expect("valid cpf"),
workload: 1,
};
let att_b = Attendee {
name: "B".to_owned(),
cpf: Cpf::new("111.111.111-11".to_owned()).expect("valid cpf"),
cpf: Cpf::new("647.748.630-09".to_owned()).expect("valid cpf"),
workload: 2,
};
let event = data.into_event(vec![att_a, att_b]);
Expand Down

0 comments on commit bb10631

Please sign in to comment.