South Africa ID Number Checksum Validation
create or replace
function validate_sa_id_number(id_number text)
returns boolean
language plpgsql
as
$$
declare
char_val char;
i int := 1;
digit int := 0;
weight int := 0;
sub_total int := 0;
total int := 0;
check_digit int;
calculated_digit int;
begin
-- Check if the id number is 13 digits long
if length(id_number) != 13 then
return false;
end if;
foreach char_val in array regexp_split_to_array(id_number, '') loop
exit when i > 12;
digit := char_val::int;
weight := (case when (i % 2) = 0 then 2 else 1 end);
sub_total := digit * weight;
-- If sub_total is two digits, sum the digits
if sub_total > 9 then
sub_total := (sub_total / 10) + (sub_total % 10);
end if;
total := total + sub_total;
i := i + 1;
end loop;
-- Calculate the check digit
check_digit := 10 - (total % 10);
if check_digit = 10 then
check_digit := 0;
end if;
raise notice 'total: %', total;
raise notice 'calculated check digit: %', check_digit;
-- Compare the calculated check digit with the last digit of the ID number
calculated_digit := substring(id_number from 13 for 1)::int;
return check_digit = calculated_digit;
end;
$$;