For a project that I’m working on I had to create MAC generator. Initially I decided that I will do it in BASH.
function gen_mac() { mac_vars=(0 1 2 3 4 5 6 7 8 9 a b c d e f) mac_base='52:53:54:' ret='' for i in {1..6}; do n=$RANDOM let 'n %= 16' ret="${ret}${mac_vars[$n]}" if [ $i -eq 2 ] || [ $i -eq 4 ]; then ret="${ret}:" fi done echo "${mac_base}${ret}" }
But unfortunately I had to rewrite it in plpgsql in order to prevent a stupid race condition that can appear.
CREATE OR REPLACE FUNCTION generate_mac() RETURNS text LANGUAGE plpgsql AS $$DECLARE mac TEXT; a CHAR; count INTEGER; BEGIN mac='52:53:54:'; FOR count IN 1..6 LOOP SELECT substring('0123456789abcdef' FROM (random()*16)::int + 1 FOR 1) INTO a; -- This fixes un issue, wehre the above SELECT returns NULL or empty string -- If for some reason we concatenate with a NULL string, the result will be NULL string WHILE a IS NULL OR a = '' LOOP SELECT substring('0123456789abcdef' FROM (random()*16)::int + 1 FOR 1) INTO a; END LOOP; mac = mac || a; IF count = 2 OR count = 4 THEN mac = mac || ':'; END IF; END LOOP; RETURN mac; END;$$;