-- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "CREATE EXTENSION "bgValidators"" to load this file. \quit -- Function: validate_bulstat(text) -- DROP FUNCTION validate_bulstat(text); CREATE OR REPLACE FUNCTION validate_bulstat(bulstat text DEFAULT ''::text) RETURNS boolean AS $BODY$ DECLARE i integer; checksum integer; checkval text; bslength integer; weights9A integer[] := array[1, 2, 3, 4, 5, 6, 7, 8]; weights9B integer[] := array[3, 4, 5, 6, 7, 8, 9, 10]; weights13A integer[] := array[2, 7, 3, 5]; weights13B integer[] := array[4, 9, 5, 7]; BEGIN bulstat := LTRIM(RTRIM(bulstat)); bslength := LENGTH(bulstat); IF NOT ((bulstat ~ '^[\d]{9}$') OR (bulstat ~ '^[\d]{13}$')) THEN -- 9 or 13 digits RETURN FALSE; END IF; IF (bslength = 9) THEN checksum := 0; FOR i IN 1 .. 8 LOOP checksum := checksum + CAST(SUBSTR(bulstat, i, 1) AS integer) * weights9A[i]; END LOOP; checksum := checksum % 11; IF (checksum <> 10) THEN checkval := CAST (checksum AS text); RETURN (checkval = SUBSTR(bulstat, 9, 1)); END IF; checksum := 0; FOR i IN 1 .. 8 LOOP checksum := checksum + CAST(SUBSTR(bulstat, i, 1) AS integer) * weights9B[i]; END LOOP; checksum := (checksum % 11) % 10; checkval := CAST (checksum AS text); RETURN (checkval = SUBSTR(bulstat, 9, 1)); END IF; IF (bslength = 13) THEN IF NOT validate_egn(SUBSTR(bulstat, 1, 9)) THEN RETURN FALSE; END IF; checksum := 0; FOR i in 9 .. 12 LOOP checksum := checksum + CAST(SUBSTR(bulstat, i, 1) AS integer) * weights13A[i - 8]; END LOOP; checksum := checksum % 11; IF (checksum <> 10) THEN checkval := CAST (checksum AS text); RETURN (checkval = SUBSTR(bulstat, 13, 1)); END IF; checksum := 0; FOR i in 9 .. 12 LOOP checksum := checksum + CAST(SUBSTR(bulstat, i, 1) AS integer) * weights13B[i - 8]; END LOOP; checksum := (checksum % 11) % 10; checkval := CAST (checksum AS text); RETURN (checkval = SUBSTR(bulstat, 9, 1)); ELSE RETURN FALSE; END IF; END; $BODY$ LANGUAGE plpgsql IMMUTABLE LEAKPROOF COST 100; ALTER FUNCTION validate_bulstat(text) OWNER TO postgres; -- Function: validate_egn(text) -- DROP FUNCTION validate_egn(text); CREATE OR REPLACE FUNCTION validate_egn(egn text DEFAULT ''::text) RETURNS boolean AS $BODY$ DECLARE retval boolean; weights integer[] := array[2, 4, 8, 5, 10, 9, 7, 3, 6]; checksum integer := 0; checkval integer; i integer; BEGIN egn := LTRIM(RTRIM(egn)); IF NOT (egn ~ '^[\d]{10}$') THEN -- 10 digits RETURN false; END IF; checkval := CAST(SUBSTR(egn, 10, 1) AS integer); FOR i IN 1..9 LOOP checksum := checksum + CAST(SUBSTR(egn, i, 1) AS integer) * weights[i]; END LOOP; checksum := (checksum % 11) % 10; RETURN (checkval = checksum); END; $BODY$ LANGUAGE plpgsql IMMUTABLE LEAKPROOF COST 100; ALTER FUNCTION validate_egn(text) OWNER TO postgres; -- Function: validate_iban(text) -- DROP FUNCTION validate_iban(text); CREATE OR REPLACE FUNCTION validate_iban(iban text DEFAULT ''::text) RETURNS boolean AS $BODY$ DECLARE ibantext text := ''; ibanlength integer; ibansum numeric(50); c char(1); i integer; BEGIN iban = LTRIM(RTRIM(UPPER(iban))); IF NOT (iban ~ '^[\dA-Z]+$') THEN RETURN FALSE; END IF; ibanlength := LENGTH(iban); iban := SUBSTR(iban, 5) || SUBSTR(iban, 1, 4); FOR i IN 1 .. ibanlength LOOP c = SUBSTR(iban, i, 1); IF (c ~ '[0-9]') THEN ibantext := ibantext || c; ELSE ibantext := ibantext || CAST(ASCII(c) - ASCII('A') + 10 AS text); END IF; END LOOP; ibansum := CAST(ibantext AS numeric(50)); RETURN ((ibansum % 97) = 1); END; $BODY$ LANGUAGE plpgsql IMMUTABLE LEAKPROOF COST 100; ALTER FUNCTION validate_iban(text) OWNER TO postgres; -- Function: validate_lnch(text) -- DROP FUNCTION validate_lnch(text); CREATE OR REPLACE FUNCTION validate_lnch(lnch text DEFAULT ''::text) RETURNS boolean AS $BODY$ DECLARE weights integer[] := array[21, 19, 17, 13, 11, 9, 7, 3, 1]; checksum integer := 0; checkval integer; i integer; BEGIN lnch := LTRIM(RTRIM(lnch)); IF NOT (lnch ~ '^[\d]{10}$') THEN -- 10 digits RETURN false; END IF; checkval := CAST(SUBSTR(lnch, 10, 1) AS integer); FOR i IN 1..9 LOOP checksum := checksum + CAST(SUBSTR(lnch, i, 1) AS integer) * weights[i]; END LOOP; checksum := (checksum % 10); RETURN (checkval = checksum); END; $BODY$ LANGUAGE plpgsql IMMUTABLE LEAKPROOF COST 100; ALTER FUNCTION validate_lnch(text) OWNER TO postgres;