Skip to content

Instantly share code, notes, and snippets.

@nazrdogan
Last active January 23, 2026 18:29
Show Gist options
  • Select an option

  • Save nazrdogan/2a896d798df15d2e783c807647a1b5ae to your computer and use it in GitHub Desktop.

Select an option

Save nazrdogan/2a896d798df15d2e783c807647a1b5ae to your computer and use it in GitHub Desktop.
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE FUNCTION public.nanoid(prefix text DEFAULT '', size int DEFAULT 21)
RETURNS text
LANGUAGE plpgsql
VOLATILE PARALLEL SAFE
AS $$
DECLARE
alphabet text := '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
idBuilder text := '';
random_size int;
counter int;
bytes bytea;
alphabetIndex int;
alphabetArray text[];
alphabetLength int := 62;
mask int := 63;
step int;
BEGIN
IF size IS NULL OR size < 1 THEN
RAISE EXCEPTION 'The size must be defined and greater than 0!';
END IF;
random_size := size - length(COALESCE(prefix, ''));
IF random_size < 1 THEN
RAISE EXCEPTION 'The size must be larger than the prefix length!';
END IF;
step := LEAST(CEIL(1.02 * mask * random_size / alphabetLength)::int, 1024);
alphabetArray := regexp_split_to_array(alphabet, '');
LOOP
bytes := gen_random_bytes(step);
FOR counter IN 0..step - 1 LOOP
alphabetIndex := (get_byte(bytes, counter) & mask) + 1;
IF alphabetIndex <= alphabetLength THEN
idBuilder := idBuilder || alphabetArray[alphabetIndex];
IF length(idBuilder) = random_size THEN
RETURN COALESCE(prefix, '') || idBuilder;
END IF;
END IF;
END LOOP;
END LOOP;
END
$$;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment