Как создать случайную строку, подходящую для идентификатора сеанса в PostgreSQL?

Я хотел бы сделать случайную строку для использования в проверке сеанса с помощью PostgreSQL. Я знаю, что могу получить случайное число с SELECT random() , поэтому я попробовал SELECT md5(random()) , но это не работает. Как я могу это сделать?

Я бы предложил это простое решение:

Это довольно простая функция, которая возвращает случайную строку заданной длины:

 Create or replace function random_string(length integer) returns text as $$ declare chars text[] := '{0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}'; result text := ''; i integer := 0; begin if length < 0 then raise exception 'Given length cannot be less than 0'; end if; for i in 1..length loop result := result || chars[1+random()*(array_length(chars, 1)-1)]; end loop; return result; end; $$ language plpgsql; 

И использование:

 select random_string(15); 

Пример вывода:

 select random_string(15) from generate_series(1,15); random_string ----------------- 5emZKMYUB9C2vT6 3i4JfnKraWduR0J R5xEfIZEllNynJR tMAxfql0iMWMIxM aPSYd7pDLcyibl2 3fPDd54P5llb84Z VeywDb53oQfn9GZ BJGaXtfaIkN4NV8 w1mvxzX33NTiBby knI1Opt4QDonHCJ P9KC5IBcLE0owBQ vvEEwc4qfV4VJLg ckpwwuG8YbMYQJi rFf6TchXTO3XsLs axdQvaLBitm6SDP (15 rows) 

Вы можете исправить свою первоначальную попытку следующим образом:

 SELECT md5(random()::text); 

Гораздо проще, чем некоторые другие предложения. 🙂

Основываясь на решении Марцина, вы можете сделать это, используя произвольный алфавит (в данном случае все 62 алфавитно-цифровых символа ASCII):

 SELECT array_to_string(array ( select substr('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', trunc(random() * 62)::integer + 1, 1) FROM generate_series(1, 12)), ''); 

Вы можете получить 128 бит случайного из UUID. Это способ выполнить работу в современном PostgreSQL.

 CREATE EXTENSION pgcrypto; SELECT gen_random_uuid(); gen_random_uuid -------------------------------------- 202ed325-b8b1-477f-8494-02475973a28f 

Возможно, стоит прочитать документы по UUID тоже

Тип данных uuid хранит универсально уникальные идентификаторы (UUID), как определено RFC 4122, ISO / IEC 9834-8: 2005 , и соответствующие стандарты. (Некоторые системы относятся к этому типу данных как глобально уникальный идентификатор или GUID.) Этот идентификатор представляет собой 128-битное количество , которое генерируется алгоритмом, выбранным, чтобы сделать его очень маловероятным, чтобы тот же идентификатор был сгенерирован кем-либо еще в известной вseleniumной, используя тот же алгоритм. Поэтому для распределенных систем эти идентификаторы обеспечивают лучшую гарантию уникальности, чем генераторы последовательности, которые уникальны только в одной базе данных.

Насколько редко происходит столкновение с UUID или допустимо? Предполагая, что они случайны,

Около 100 триллионов версий 4 UUID должны быть созданы, чтобы иметь 1 миллиард шансов на один дубликат («столкновение»). Вероятность одного столкновения возрастает до 50% только после того, как было создано 261 UUID (2,3 x 1018 или 2,3 квинтиллиона). Связав эти числа с базами данных и рассматривая вопрос о том, является ли вероятность столкновения UUID версии 4 пренебрежимо малой, рассмотрите файл, содержащий 2,3 квинтиллиона UUID версии 4 с 50% -ной вероятностью сдерживания одного столкновения UUID. Это было бы 36 экзабайт в размере, не предполагая никаких других данных или накладных расходов, в тысячи раз превышающих самые большие базы данных, которые в настоящее время существуют, которые находятся в порядке петабайт. В размере 1 миллиарда UUID, генерируемых в секунду, потребуется 73 года для создания UUID для файла. Для его хранения потребуется также 3,6 миллиона 10-ти терабайтных жестких дисков или кассетных картриджей, не требуя резервных копий или избыточности. Чтение файла с типичной скоростью передачи данных «один-на-буфер» 1 гигабит в секунду потребует более 3000 лет для одного процессора. Так как неустранимая скорость чтения при чтении дисков составляет 1 бит на 1018 бит, в лучшем случае, в то время как файл будет содержать около 1020 бит, просто чтение файла один раз из конца в конец приведет к по меньшей мере примерно в 100 раз больше ошибок, читать UUID, чем дубликаты. Ошибки памяти, сети, питания и других аппаратных и программных ошибок, несомненно, будут в тысячи раз чаще, чем проблемы дублирования UUID. – источник википедии

В итоге,

  • UUID стандартизирован.
  • gen_random_uuid() – 128 бит случайного хранения в 128 бит (2 ** 128 комбинаций). 0-отходов.
  • random() генерирует только 52 бит случайных чисел в PostgreSQL (2 ** 52 комбинации).
  • md5() хранящийся как UUID, составляет 128 бит, но он может быть только случайным, как его вход ( 52 бит при использовании random() )
  • md5() сохраняется как текст 288 бит, но он может быть только так же случайным, как и его вход ( 52 бит при использовании random() ) – более чем в два раза больше UUID и доли случайности)
  • md5() как hash, может быть настолько оптимизирован, что он эффективно не делает.
  • UUID очень эффективен для хранения: PostgreSQL предоставляет тип, который составляет ровно 128 бит. В отличие от text и varchar и т. Д., varlena хранятся как varlena которых есть накладные расходы для длины строки.
  • PostgreSQL nifty UUID поставляется с некоторыми стандартными операторами, отливками и функциями.

Недавно я играл с PostgreSQL, и я думаю, что нашел немного лучшего решения, используя только встроенные методы PostgreSQL – нет pl / pgsql. Единственным ограничением является то, что в настоящее время он генерирует только строки UPCASE или числа или строчные строки.

 template1=> SELECT array_to_string(ARRAY(SELECT chr((65 + round(random() * 25)) :: integer) FROM generate_series(1,12)), ''); array_to_string ----------------- TFBEGODDVTDM template1=> SELECT array_to_string(ARRAY(SELECT chr((48 + round(random() * 9)) :: integer) FROM generate_series(1,12)), ''); array_to_string ----------------- 868778103681 

Второй аргумент метода generate_series определяет длину строки.

Если вы не активны по умолчанию, вы можете активировать одно из основных расширений:

 CREATE EXTENSION IF NOT EXISTS pgcrypto; 

Тогда ваше утверждение становится простым вызовом gen_salt (), который генерирует случайную строку:

 select gen_salt('md5') from generate_series(1,4); gen_salt ----------- $1$M.QRlF4U $1$cv7bNJDM $1$av34779p $1$ZQkrCXHD 

Ведущее число – это hash-идентификатор. Доступны несколько алгоритмов, каждый из которых имеет свой собственный идентификатор:

  • md5: $ 1 $
  • bf: $ 2a $ 06 $
  • des: no identifier
  • xdes: _J9 ..

Дополнительная информация о расширениях:


РЕДАКТИРОВАТЬ

Как указывает Эван Кэррол, с gen_random_uuid() вы можете использовать gen_random_uuid()

http://www.postgresql.org/docs/9.4/static/pgcrypto.html

Пожалуйста, используйте string_agg !

 SELECT string_agg (substr('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', ceil (random() * 62)::integer, 1), '') FROM generate_series(1, 45); 

Я использую это с MD5 для создания UUID. Я просто хочу случайное значение с большим количеством бит, чем random () целое число.

Я не думаю, что вы ищете случайную строку как таковую. Что вам нужно для проверки сеанса, это строка, которая гарантированно будет уникальной. Вы храните информацию о проверке сеанса для аудита? В этом случае строка должна быть уникальной между сеансами. Я знаю два, довольно простые подходы:

  1. Используйте последовательность. Хорошо подходит для использования в одной базе данных.
  2. Используйте UUID. Универсально уникальна, так хороша и в распределенных средах.

UUID гарантированно уникальны в силу своего алгоритма генерации; эффективно маловероятно, что вы будете генерировать два одинаковых числа на любой машине в любое время (обратите внимание, что это намного сильнее, чем на случайных строках, которые имеют гораздо меньшую периодичность, чем UUID).

Вам нужно загрузить расширение uuid-ossp для использования UUID. После установки вызовите любую из доступных функций uuid_generate_vXXX () в ваших вызовах SELECT, INSERT или UPDATE. Тип uuid представляет собой 16-байтовое число, но также имеет строковое представление.

select * from md5(to_char(random(), '0.9999999999999999'));

Параметр INTEGER определяет длину строки. Гарантировано, чтобы охватить все 62 алфавитных символа с равной вероятностью (в отличие от некоторых других решений, плавающих в Интернете).

 CREATE OR REPLACE FUNCTION random_string(INTEGER) RETURNS TEXT AS $BODY$ SELECT array_to_string( ARRAY ( SELECT substring( '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' FROM (ceil(random()*62))::int FOR 1 ) FROM generate_series(1, $1) ), '' ) $BODY$ LANGUAGE sql VOLATILE; 

@Kavius ​​рекомендуется использовать pgcrypto , но вместо gen_salt , а что же gen_random_bytes ? А как насчет sha512 вместо md5 ?

 create extension if not exists pgcrypto; select digest(gen_random_bytes(1024), 'sha512'); 

Docs:

F.25.5. Функции случайных данных

gen_random_bytes (count integer) возвращает bytea

Возвращает количество криптографически сильных случайных байтов. Одновременно может быть извлечено не более 1024 байт. Это делается для того, чтобы избежать слива пула генераторов случайности.

 select encode(decode(md5(random()::text), 'hex')||decode(md5(random()::text), 'hex'), 'base64') 
  • Как работает ORDER BY RAND () MySQL?
  • Генератор случайных строк, возвращающий одну строку
  • Алгоритм произвольного участка
  • Как настроить пользовательское семя для генератора псевдослучайных чисел
  • Случайный взвешенный выбор в Java
  • Случайные точки внутри параллелограмма
  • Создание случайных чисел без дубликатов
  • Выберите уникальные случайные числа
  • Случайная строка, которая соответствует регулярному выражению
  • Как создать случайную буквенно-цифровую строку в C ++?
  • Почему этот код использует случайные строки для печати «hello world»?
  • Давайте будем гением компьютера.