Saya ingin membuat string acak untuk digunakan dalam verifikasi sesi menggunakan PostgreSQL. Saya tahu saya bisa mendapatkan nomor acak dengan SELECT random()
, jadi saya mencoba SELECT md5(random())
, tetapi tidak berhasil. Bagaimana saya bisa melakukan ini?
postgresql
random
gersh
sumber
sumber
random()
ness tidak diperlukan). Jika bukan itu yang saya asumsikan, maka jawaban saya harus disesuaikan dengan pertanyaan yang lebih halus.Jawaban:
Saya akan menyarankan solusi sederhana ini:
Ini adalah fungsi yang cukup sederhana yang mengembalikan string acak dengan panjang yang diberikan:
Dan penggunaannya:
Contoh keluaran:
sumber
chars[1+random()*(array_length(chars, 1)-1)]
denganchars[ceil(61 * random())]
random()
mendapat panggilanlength
kali (seperti di banyak solusi lainnya). Adakah cara yang lebih efisien untuk memilih dari 62 karakter setiap kali? Bagaimana kinerjanya dibandingkanmd5()
?ORDER BY random()
. Mana yang lebih cepat?Anda dapat memperbaiki upaya awal Anda seperti ini:
Jauh lebih sederhana daripada beberapa saran lainnya. :-)
sumber
SELECT concat(md5(random()::text), md5(random()::text));
Dan jika Anda ingin berada di tengah-tengah (50 karakter misalnya), Anda dapat mengambil substringnya:SELECT substr(concat(md5(random()::text), md5(random()::text)), 0, 50);
gen_random_uuid()
: lebih cepat, lebih keacakan, lebih efisien disimpan dalam database.SELECT md5(random()::text||random()::text);
, atauSELECT md5(random()::text||random()::text||random()::text);
Berdasarkan solusi Marcin, Anda dapat melakukan ini untuk menggunakan alfabet arbitrer (dalam hal ini, semua 62 karakter alfanumerik ASCII):
sumber
Check out this for a totally different method using gen_random_uuid()
: lebih cepat, lebih acak, lebih efisien disimpan dalam database.Anda bisa mendapatkan 128 bit acak dari UUID. Ini adalah metode untuk menyelesaikan pekerjaan di PostgreSQL modern.
Mungkin ada baiknya membaca dokumen tentang UUID juga
Seberapa jarang tabrakan dengan UUID, atau dapat ditebak? Dengan asumsi mereka acak,
sumber: wikipedia
Singkatnya,
gen_random_uuid()
adalah 128 bit acak yang disimpan dalam 128 bit (2 ** 128 kombinasi). 0-limbah.random()
hanya menghasilkan 52 bit acak di PostgreSQL (2 ** 52 kombinasi).md5()
disimpan karena UUID adalah 128 bit, tetapi hanya dapat seacak inputnya ( 52 bit jika menggunakanrandom()
)md5()
disimpan sebagai teks adalah 288 bit, tetapi hanya dapat seacak inputnya ( 52 bit jika menggunakanrandom()
) - lebih dari dua kali ukuran UUID dan sebagian kecil dari keacakan)md5()
sebagai hash, bisa sangat dioptimalkan sehingga tidak efektif banyak.text
danvarchar
, dll yang menyimpan sebagaivarlena
yang memiliki overhead untuk panjang string.sumber
Saya baru-baru ini bermain dengan PostgreSQL, dan saya rasa saya telah menemukan solusi yang sedikit lebih baik, hanya menggunakan metode PostgreSQL bawaan - tanpa pl / pgsql. Satu-satunya batasan adalah saat ini hanya menghasilkan string UPCASE, atau angka, atau string huruf kecil.
Argumen kedua untuk
generate_series
metode menentukan panjang string.sumber
array_to_string(ARRAY(SELECT chr((65 + round((random()+my_id-my) * 25)) :: integer) FROM generate_series(1,8)), '')
array_to_string(ARRAY(SELECT chr((65 + round((random() * 25 + id) :: integer % 25 )) :: integer) FROM generate_series(1, 60)), '');
Silakan gunakan
string_agg
!Saya menggunakan ini dengan MD5 untuk menghasilkan UUID juga. Saya hanya ingin nilai acak dengan lebih banyak bit daripada
random ()
integer.sumber
random()
sampai saya mendapatkan jumlah bit yang saya inginkan. Baiklah.Meskipun tidak aktif secara default, Anda dapat mengaktifkan salah satu ekstensi inti:
Kemudian pernyataan Anda menjadi panggilan sederhana ke gen_salt () yang menghasilkan string acak:
Nomor terdepan adalah pengenal hash. Beberapa algoritme tersedia, masing-masing dengan pengenalnya sendiri:
Informasi lebih lanjut tentang ekstensi:
EDIT
Seperti yang ditunjukkan oleh Evan Carrol, mulai v9.4 Anda dapat menggunakan
gen_random_uuid()
http://www.postgresql.org/docs/9.4/static/pgcrypto.html
sumber
$1$
? Itu adalah pengenal tipe hash (md5 == 1), sisanya adalah nilai acak.Saya tidak berpikir bahwa Anda mencari string acak itu sendiri. Apa yang Anda perlukan untuk verifikasi sesi adalah string yang dijamin unik. Apakah Anda menyimpan informasi verifikasi sesi untuk audit? Dalam hal ini Anda perlu string menjadi unik di antara sesi. Saya tahu dua pendekatan yang agak sederhana:
UUID dijamin unik berdasarkan algoritma mereka untuk pembuatan; secara efektif sangat tidak mungkin bahwa Anda akan menghasilkan dua nomor identik pada mesin manapun, kapanpun, selamanya (perhatikan bahwa ini jauh lebih kuat daripada pada string acak, yang memiliki periodisitas yang jauh lebih kecil daripada UUID).
Anda perlu memuat ekstensi uuid-ossp untuk menggunakan UUID. Setelah terinstal, panggil salah satu fungsi uuid_generate_vXXX () yang tersedia di panggilan SELECT, INSERT atau UPDATE Anda. Tipe uuid adalah angka 16-byte, tetapi juga memiliki representasi string.
sumber
Parameter INTEGER menentukan panjang string. Dijamin untuk mencakup semua 62 karakter alfanum dengan probabilitas yang sama (tidak seperti beberapa solusi lain yang beredar di Internet).
sumber
Check out this for a totally different method using gen_random_uuid()
: lebih cepat, lebih acak, lebih efisien disimpan dalam database.gen_random_uuid()
sejauh yang saya tahu , muncul di Versi 9.4, yang dirilis pada 2014-12-18, lebih dari setahun setelah jawaban Anda menurunkan suara. Nitpick tambahan: jawabannya hanya 3 1/2 tahun :-) Tapi Anda benar, sekarang kami punyagen_random_uuid()
, inilah yang harus digunakan. Karenanya saya akan memberi suara positif pada jawaban Anda.@Kavius merekomendasikan penggunaan
pgcrypto
, tetapi daripadagen_salt
, bagaimanagen_random_bytes
? Dan bagaimana kalausha512
bukanmd5
?Dokumen:
sumber
select * from md5(to_char(random(), '0.9999999999999999'));
sumber
sumber