Last active
January 23, 2026 18:29
-
-
Save nazrdogan/2a896d798df15d2e783c807647a1b5ae to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| 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