2 releases
0.1.3 | Oct 30, 2024 |
---|---|
0.1.2 |
|
0.1.1 |
|
0.1.0 | Oct 27, 2024 |
#238 in Authentication
44KB
929 lines
PESEL validation and detail extraction with multiple data layout implementations.
Definitions
PESEL: YYMMDDOOOOC
YY
- Last two digits of year of birthMM
- Month of birth (shifted depending on year of birth as shown by the table below)
Year | 1800 - 1899 | 1900 - 1999 | 2000 - 2099 | 2100 - 2199 | 2200 - 2299 |
---|---|---|---|---|---|
Month shift | +80 | 0 | +20 | +40 | +60 |
DD
- Day of birthOOOO
- Ordinal number, where the last digit denotes the gender ([0, 2, 4, 6, 8] = female, [1, 3, 5, 7, 9] = male)C
- Control number
Usage
There are two PESEL structs provided by the crate, both implementing the PeselTrait
.
-
crate::bit_fields::Pesel
- Stores each section of the PESEL in the following layout:7 bits | YY | 5 bits | MM | 5 bits | DD | 5 bits | OOOO | 5 bits | C
, where in between bits are unused. Extracting each field is done using bitwise operations. You can get the human readable number usingu64::from
. -
crate::human_redable::Pesel
- Stores the PESEL as a plain number, extracting each field requires modulo and division operations, if often accessing individual fields is important to you, you should probably usecrate::bit_fields::Pesel
.
If you just need to validate a number or extract a specific section without using the structs, you could use functions in the lib root. Most of these functions won't check if the value they're returning is valid, unlike the structs who are guaranteed to always return a valid value.
Examples
Function that takes a name and welcomes the person based on date of birth and gender from the PESEL. Implemented using crate::bit_fields::Pesel
because we're mostly reading the fields.
use pesel_rs::{prelude::*, bit_fields::Pesel};
fn welcome(first_name: &str, pesel: u64) {
match Pesel::try_from(pesel) {
Ok(pesel) => {
if pesel.date_of_birth() > NaiveDate::from_ymd_opt(2015, 1, 1).unwrap() {
let gender = if pesel.gender() == Gender::Male { "boy" } else { "girl" };
println!("Wow {first_name}! You're such a young {gender}!");
} else {
println!("{first_name}, you're very old, I'm sorry 😞");
}
}
Err(_) => println!("Huh, what you gave me doesn't seem to be a valid pesel {first_name}..."),
}
}
Function finding a pesel with the oldest date of birth. Working with a generic PESEL, we introduce additional bounds (required by PeselTrait
).
use pesel_rs::prelude::*;
fn oldest<T: PeselTrait>(pesels: &[T])
where
u64: From<T>,
for<'a> u64: From<&'a T>
{
assert!(pesels.len() > 0);
let mut oldest_index = 0;
pesels.iter().skip(1).enumerate().for_each(|(i, pesel)| {
if pesels[oldest_index].date_of_birth() < pesel.date_of_birth() {
oldest_index = i;
}
});
let date_of_birth = pesels[oldest_index].date_of_birth();
println!("PESEL nr. {oldest_index} is the oldest! Born at {date_of_birth}")
}
Dependencies
~1.2–2MB
~36K SLoC