Created
April 25, 2016 21:26
-
-
Save vpavic/d68e45e6f62b94c62295bcebba4186d2 to your computer and use it in GitHub Desktop.
PostgreSQL functions for Croatian Personal Identification Number (OIB)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- PostgreSQL functions for Croatian Personal Identification Number (OIB) | |
-- | |
-- Reference: | |
-- https://en.wikipedia.org/wiki/Personal_identification_number_(Croatia) | |
-- http://www.regos.hr/UserDocsImages/KONTROLA%20OIB-a.pdf | |
CREATE OR REPLACE FUNCTION hr_pin_control_number(pin_base TEXT) RETURNS INTEGER AS $$ | |
DECLARE | |
pin_digit INTEGER; | |
control INTEGER; | |
BEGIN | |
IF length(pin_base) != 10 THEN | |
RAISE EXCEPTION 'Invalid input ''%''', pin_base | |
USING HINT = 'Input must be exactly 10 digits long'; | |
END IF; | |
IF NOT textregexeq(pin_base, '^[[:digit:]]+$') THEN | |
RAISE EXCEPTION 'Invalid input ''%''', pin_base | |
USING HINT = 'Input must contain only digits'; | |
END IF; | |
FOR i IN 1..10 LOOP | |
pin_digit := substr(pin_base, i, 1)::INTEGER; | |
IF i = 1 THEN | |
control := pin_digit + 10; | |
ELSE | |
control := pin_digit + control; | |
END IF; | |
control := control % 10; | |
IF control = 0 THEN | |
control := 10; | |
END IF; | |
control := control * 2; | |
control := control % 11; | |
END LOOP; | |
control := 11 - control; | |
control := control % 10; | |
RETURN control; | |
END; | |
$$ LANGUAGE plpgsql; | |
CREATE OR REPLACE FUNCTION hr_pin_is_valid(pin TEXT) RETURNS BOOLEAN AS $$ | |
DECLARE | |
control INTEGER; | |
BEGIN | |
IF length(pin) != 11 THEN | |
RAISE EXCEPTION 'Invalid input ''%''', pin | |
USING HINT = 'Input must be exactly 11 digits long'; | |
END IF; | |
IF NOT textregexeq(pin, '^[[:digit:]]+$') THEN | |
RAISE EXCEPTION 'Invalid input ''%''', pin | |
USING HINT = 'Input must contain only digits'; | |
END IF; | |
control := hr_pin_control_number(substr(pin, 1, 10)); | |
RETURN control = substr(pin, 11, 1)::INTEGER; | |
END; | |
$$ LANGUAGE plpgsql; | |
CREATE OR REPLACE FUNCTION hr_pin_generate_random() RETURNS TEXT AS $$ | |
DECLARE | |
pin_digits INTEGER[]; | |
pin_base TEXT; | |
control INTEGER; | |
BEGIN | |
FOR i IN 1..10 LOOP | |
pin_digits[i] := floor(random() * 10); | |
END LOOP; | |
pin_base = array_to_string(pin_digits, ''); | |
control := hr_pin_control_number(pin_base); | |
RETURN concat(pin_base, control); | |
END; | |
$$ LANGUAGE plpgsql; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment