Вы можете генерировать 15-битные случайные числа, используя эту пару хранимых процедур:
-- @(#)$Id: random.spl,v 1.2 1997/12/08 19:31:44 johnl Exp $
--
-- Simple emulation of SRAND and RAND in SPL
-- Using random number generator suggested by C standard (ISO 9899:1990)
CREATE PROCEDURE sp_setseed(n INTEGER)
DEFINE GLOBAL seed DECIMAL(10) DEFAULT 1;
LET seed = n;
END PROCEDURE;
CREATE PROCEDURE sp_random() RETURNING INTEGER;
DEFINE GLOBAL seed DECIMAL(10) DEFAULT 1;
DEFINE d DECIMAL(20,0);
LET d = (seed * 1103515245) + 12345;
-- MOD function does not handle 20-digit values... Dammit!!
LET seed = d - 4294967296 * TRUNC(d / 4294967296);
RETURN MOD(TRUNC(seed / 65536), 32768);
END PROCEDURE;
Вы можете использовать эти числа, чтобы сгенерировать последовательность буквенно-цифровых символов, с более или менее утонченной точностью. Простой подход использует случайное число по модулю количества буквенно-цифровых символов (хотите ли вы [A-Z0-9]
или [a-z0-9]
или [A-Za-z0-9]
, или что-то еще) и выбираете символ каждый раз. Существует вероятность неравного распределения, если вы не будете осторожны (потому что, если есть 32768 возможных случайных чисел и у вас есть 36 возможных символов, 8 символов будут иметь 911 из 32768 шансов быть выбранными, в то время как остальные 28 будут иметь только 910 из 32768 шансов быть выбранными (и проблема больше, если вы используете 62 символа - строчные, прописные и цифры). Есть способы справиться с этим, если это проблема.
Вот простой, слегка искаженный подход на работе:
-- @(#)$Id: randomstring.spl,v 1.1 2018/08/27 16:43:59 jonathanleffler Exp $
--
-- Generate a random sequence of characters from given list
CREATE FUNCTION sp_randomstring(str VARCHAR(255), num INTEGER)
RETURNING VARCHAR(255) AS random_string;
DEFINE r VARCHAR(255);
DEFINE i INTEGER;
DEFINE n INTEGER;
DEFINE j INTEGER;
LET r = "";
LET n = LENGTH(str);
FOR i = 1 TO num
LET j = MOD(sp_random(), n) + 1;
LET r = r || SUBSTR(str, j, 1);
END FOR;
RETURN r;
END FUNCTION;
EXECUTE FUNCTION sp_randomstring("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 20);
EXECUTE FUNCTION sp_randomstring("abcdefghijklmnopqrstuvwxyz0123456789", 21);
EXECUTE FUNCTION sp_randomstring("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 22);
EXECUTE FUNCTION sp_randomstring("abcdefghijklmnopqrstuvwxyz0123456789", 23);
EXECUTE FUNCTION sp_randomstring("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 24);
EXECUTE FUNCTION sp_randomstring("abcdefghijklmnopqrstuvwxyz0123456789", 24);
EXECUTE FUNCTION sp_randomstring("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 23);
EXECUTE FUNCTION sp_randomstring("abcdefghijklmnopqrstuvwxyz0123456789", 22);
EXECUTE FUNCTION sp_randomstring("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 21);
EXECUTE FUNCTION sp_randomstring("abcdefghijklmnopqrstuvwxyz0123456789", 20);
Пример вывода:
087TTLGDMSNXMAFL7PJG
cklp14dfk66308lxkzjyu
6JDTOJLC47UE9GWSHRBH55
gwpmrfwwwcykgqbn494bmeh
TNY3U3VMHN01UZS1GV4LOF0K
tm38v8qwqj6o0vrsh9gbb0w6
YF6QP6NT3VK5ARTFDL1N32B
vrb9pvww5cw6egsz9tniex
9OIY799Z694DBENBDFSFE
1gkj5adm3bswlo26wd5i
Я не установил начальное значение, поэтому код генерирует одну и ту же последовательность каждый раз. Вы можете использовать последовательность для генерации нового начального числа каждый раз, или вы можете сделать что-то еще для начального заполнения генератора. Семя является частным для каждого сеанса.