PostgreSQL এ সেশন আইডির জন্য উপযুক্ত এমন একটি এলোমেলো স্ট্রিং আপনি কীভাবে তৈরি করবেন?


101

আমি পোস্টগ্রেএসকিউএল ব্যবহার করে সেশন যাচাইয়ের জন্য একটি এলোমেলো স্ট্রিং তৈরি করতে চাই। আমি জানি আমি এর সাথে একটি এলোমেলো নম্বর পেতে পারি SELECT random(), তাই চেষ্টা করেছি SELECT md5(random()), কিন্তু এটি কার্যকর হয় না। কিভাবে আমি এটি করতে পারব?


আরেকটি সমাধান এখানে পাওয়া যাবে stackoverflow.com/a/13675441/398670
ক্রেগ রিঞ্জার

7
আমি শিরোনামটি সম্পাদনা করেছি যাতে বিদ্যমান উত্তরগুলি এখনও পুরোপুরি সঠিকভাবে বোঝায় এবং ইভানের উত্তরগুলি আরও কিছুটা আধুনিক এনে দেয়। আমি কোনও সামগ্রীর বিবাদের জন্য এই পুরানো প্রশ্নটিকে লক করতে চাই না - তাই আসুন দয়া করে সমস্ত উত্তরের সাথে মিলে কোনও অতিরিক্ত সম্পাদনা করি ।
টিম পোস্ট

4
শীতল, দেখা যাক @gersh এই প্রশ্নটি পরিষ্কার করতে পারে কিনা কারণ তার আসল অভিপ্রায় সম্পর্কে বৈধ মতপার্থক্য রয়েছে। যদি তার আসল অভিপ্রায়টি আমি যা অনুমান করি তা হ'ল, এই উত্তরগুলির মধ্যে অনেকগুলিই সামঞ্জস্য, ডাউনভোট বা প্রত্যাহার করা দরকার। এবং, সম্ভবত পরীক্ষার উদ্দেশ্যে (বা এর মতো) স্ট্রিং উত্পন্ন করার বিষয়ে একটি নতুন প্রশ্ন উত্থাপন করা উচিত (যেখানে random()নেস প্রয়োজন হয় না)। যদি আমি এটি অনুমান করি না হয় তবে আমার উত্তরটির পরিবর্তে পরিশ্রুত প্রশ্নে আবশ্যক।
ইভান ক্যারল

5
@ ইভানক্রোল - জেরেশ সর্বশেষ 21 নভেম্বর 2015-এ দেখা
গিয়েছিল

5
যে কেউ> বছরে এই প্রশ্নে আসছেন> ২০১৩ সালে ইভানের উত্তরটি stackoverflow.com/a/41608000/190234 বিবেচনা করুন কারণ এটি যখন এমন অনুসন্ধান পদ্ধতিগুলি উত্তর জিজ্ঞাসা করেছিল এবং উত্তর দিয়েছিল তখন যে পদ্ধতিগুলি উপলভ্য ছিল না সেগুলি ব্যবহার করে।
মার্সিন র্যাকজকোভস্কি 12'17

উত্তর:


87

আমি এই সহজ সমাধানটি পরামর্শ দেব:

এটি একটি বেশ সহজ ফাংশন যা প্রদত্ত দৈর্ঘ্যের এলোমেলো স্ট্রিং প্রদান করে:

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)

6
এই দ্রষ্টব্যটি অক্ষরের অ্যারে - 0 এবং z - এর অর্ধেকের শেষে মানগুলি ব্যবহার করে যতক্ষণ বাকী হিসাবে অর্ধেকবার। অক্ষরের একটি আরো এমনকি বিতরণের জন্য, আমি প্রতিস্থাপিত chars[1+random()*(array_length(chars, 1)-1)]সঙ্গেchars[ceil(61 * random())]
PreciousBodilyFluids

random()lengthবার বলা হয় (অন্যান্য সমাধানের অনেকের মতো)। 62 টি অক্ষর থেকে প্রতিটি বার চয়ন করার জন্য আরও কার্যকর উপায় আছে? এটি তুলনায় কিভাবে সম্পাদন করে md5()?
ma11 শেই 28

আমি অন্য একটি সমাধান পেয়েছি যা ব্যবহার করে ORDER BY random()। কোনটি দ্রুত?
ma11 শেই 28

4
এটি লক্ষণীয় যে এলোমেলোভাবে ERend 48 ব্যবহার করতে পারে যা কোনও সিএসপিআরএনজি নয়, আপনি কেবল পিজক্রিপ্টো ব্যবহার করেই ভাল।
ইয়াহুর

4
এটি একটি সুরক্ষিত এলোমেলো নম্বর জেনারেটর ব্যবহার করে না এবং এটি সেশন আইডির জন্য এত ভাল নয় Good দেখুন: স্ট্যাকওভারফ্লো.com
সুডো

245

আপনি আপনার প্রাথমিক প্রচেষ্টাটি এটি ঠিক করতে পারেন:

SELECT md5(random()::text);

অন্যান্য পরামর্শগুলির তুলনায় অনেক সহজ। :-)


17
দ্রষ্টব্য যে এটি কেবলমাত্র "hex ডিজিটের বর্ণমালার" {0..9, a..f} এর উপর স্ট্রিং প্রদান করে। পর্যাপ্ত নাও হতে পারে - আপনি তাদের সাথে কী করতে চান তার উপর নির্ভর করে।
ল্যারিক্স ডিসিডুয়া

ফিরে আসা স্ট্রিংয়ের দৈর্ঘ্য কত? এটিকে আরও দীর্ঘতর স্ট্রিং ফিরিয়ে দেওয়ার কোনও উপায় আছে কি?
অ্যান্ড্রুর্ক

9
হেক্সাডেসিমালে উপস্থাপিত হলে, MD5 স্ট্রিংয়ের দৈর্ঘ্য সর্বদা 32 টি অক্ষর। আপনি যদি দৈর্ঘ্যের 64 স্ট্রিং চান, আপনি 2 এমডি 5 স্ট্রিংকে একত্রীকরণ করতে পারেন: SELECT concat(md5(random()::text), md5(random()::text)); এবং আপনি যদি মাঝখানে কোথাও চান (উদাহরণস্বরূপ 50 টি অক্ষর), আপনি এর একটি স্ট্রিং নিতে পারেন: SELECT substr(concat(md5(random()::text), md5(random()::text)), 0, 50);
জিমি টাইরেল

4
সেশন আইডসের জন্য খুব ভাল সমাধান নয়, খুব বেশি এলোমেলো নয়। উত্তরটিও 6 বছরের পুরানো। এটি সম্পূর্ণ ভিন্ন পদ্ধতির জন্য ব্যবহার করে দেখুনgen_random_uuid() : দ্রুত, আরও এলোমেলোতা, আরও দক্ষতার সাথে ডেটাবেজে সঞ্চিত।
ইভান ক্যারল

@Evan আপনি আরো একটি এক্সটেনশন আপনি যা করতে পারেন ছাড়া 'যদৃচ্ছতা' চান তাহলে SELECT md5(random()::text||random()::text);, বাSELECT md5(random()::text||random()::text||random()::text);

31

মার্সিনের সমাধানের উপর ভিত্তি করে, আপনি একটি স্বেচ্ছাসেবী বর্ণমালা ব্যবহার করতে এটি করতে পারেন (এই ক্ষেত্রে, সমস্ত 62 এএসসিআইআই বর্ণমালা অক্ষর):

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

ধীরে ধীরে, এলোমেলো নয় বা সঞ্চয় করার মতো দক্ষ নয়। সেশন আইডসের জন্য খুব ভাল সমাধান নয়, খুব বেশি এলোমেলো নয়। উত্তরটিও 6 বছরের পুরানো। Check out this for a totally different method using gen_random_uuid(): দ্রুত, আরও এলোমেলোতা, আরও দক্ষতার সাথে ডাটাবেসে সঞ্চিত।
ইভান ক্যারল

24

আপনি কোনও ইউইউডি থেকে 128 বিট র্যান্ডম পেতে পারেন। আধুনিক PostgreSQL এ কাজটি করার জন্য এই পদ্ধতিটি।

CREATE EXTENSION pgcrypto;
SELECT gen_random_uuid();

           gen_random_uuid            
--------------------------------------
 202ed325-b8b1-477f-8494-02475973a28f

ইউআইডি-তেও ডক্সগুলি পড়ার উপযুক্ত হতে পারে

আরএফসি 4122, আইএসও / আইসিসি 9834-8: 2005 , এবং সম্পর্কিত মান দ্বারা বর্ণিত ডেটা টাইপ ইউইড সর্বজনীন ইউনিক আইডেন্টিফায়ার (ইউইউডি) সঞ্চয় করে। (কিছু সিস্টেমগুলি পরিবর্তে বিশ্বব্যাপী অনন্য শনাক্তকারী বা জিইউইডি হিসাবে এই ডেটা টাইপকে উল্লেখ করে)) এই শনাক্তকারীটি একটি 128-বিট পরিমাণ যা কোনও অ্যালগোরিদম দ্বারা উত্পন্ন যা খুব সম্ভবত সম্ভাব্যরূপে তৈরি করতে পারে যে একই পরিচয়কারী অন্য কারও দ্বারা উত্পন্ন হবে make একই অ্যালগরিদম ব্যবহার করে জানা মহাবিশ্বে। সুতরাং, বিতরণ সিস্টেমগুলির জন্য, এই শনাক্তকারীরা সিকোয়েন্স জেনারেটরের তুলনায় আরও ভাল স্বাতন্ত্র্যের গ্যারান্টি সরবরাহ করে, যা কেবলমাত্র একটি একক ডাটাবেসের মধ্যে অনন্য।

ইউইউডি, বা অনুমানযোগ্য সাথে সংঘর্ষ কতটা বিরল? ধরে নিচ্ছি তারা এলোমেলো,

একক নকলের ("সংঘর্ষ") এর এক বিলিয়ন সম্ভাবনা পাওয়ার জন্য প্রায় 100 ট্রিলিয়ন সংস্করণ 4 ইউআইডি উত্পন্ন করতে হবে। ২ 26১ টি ইউআইডি (২.৩ x 10 ^ 18 বা ২.৩ কুইন্টিলিয়ন) তৈরি হওয়ার পরে কেবল একটি সংঘর্ষের সুযোগ 50% এ পৌঁছায়। এই সংখ্যাগুলিকে ডাটাবেসের সাথে সম্পর্কিত করা এবং সংস্করণ 4 ইউআইডি সংঘর্ষের সম্ভাবনা নগণ্য কিনা তা বিবেচনা করে, একটি ইউআইডি সংঘর্ষের 50% সম্ভাবনা সহ 2.3 কুইন্টিলিয়ন সংস্করণ 4 ইউআইডিযুক্ত একটি ফাইল বিবেচনা করুন। এটি অন্য কোনও ডেটা বা ওভারহেড ধরে না রেখে আকারে 36 এক্সবাইট হবে, বর্তমানে পেটবাইটের ক্রম অনুসারে বিদ্যমান বৃহত্তম ডাটাবেসগুলির চেয়ে কয়েক হাজার গুণ বড়। প্রতি সেকেন্ডে 1 বিলিয়ন ইউআইডি-র উত্পাদিত হারে, ফাইলটির জন্য ইউইউডিগুলি তৈরি করতে 73 বছর সময় লাগবে। এটির জন্যও প্রায় 3 প্রয়োজন হবে। 6 মিলিয়ন 10-টেরাবাইট হার্ড ড্রাইভ বা টেপ কার্তুজ এটি সঞ্চয় করতে, কোনও ব্যাকআপ বা অপ্রয়োজনীয়তা না ধরে। একটি সাধারণ "ডিস্ক-টু-বাফার" প্রতি সেকেন্ডে 1 গিগাবিট স্থানান্তর হারে ফাইলটি পড়তে একক প্রসেসরের জন্য 3000 বছরের বেশি সময় লাগতে পারে। যেহেতু ড্রাইভের অপরিবর্তনযোগ্য পঠন ত্রুটির হার 1018 বিট পড়লে প্রতি 1 বিট হয় তবে সর্বোপরি, যখন ফাইলটি প্রায় 1020 বিট ধারণ করে, কেবল একবার ফাইলটি প্রান্ত থেকে শেষ পর্যন্ত পড়ার ফলে কমপক্ষে প্রায় 100 গুণ বেশি ভুল- সদৃশগুলির চেয়ে ইউআইডি পড়ুন। স্টোরেজ, নেটওয়ার্ক, শক্তি এবং অন্যান্য হার্ডওয়্যার এবং সফ্টওয়্যার ত্রুটিগুলি নিঃসন্দেহে ইউইউডি সদৃশ সমস্যার তুলনায় কয়েক হাজার গুণ বেশি ঘন ঘন হবে। প্রতি সেকেন্ডে 1 গিগাবিট স্থানান্তর হারের জন্য একটি একক প্রসেসরের জন্য 3000 বছরের বেশি সময় লাগবে। যেহেতু ড্রাইভের অপরিবর্তনযোগ্য পঠন ত্রুটির হার 1018 বিট পড়লে প্রতি 1 বিট হয় তবে সর্বোপরি, যখন ফাইলটি প্রায় 1020 বিট ধারণ করে, কেবল একবার ফাইলটি প্রান্ত থেকে শেষ পর্যন্ত পড়ার ফলে কমপক্ষে প্রায় 100 গুণ বেশি ভুল- সদৃশগুলির তুলনায় ইউআইডিগুলি পড়ুন। স্টোরেজ, নেটওয়ার্ক, শক্তি এবং অন্যান্য হার্ডওয়্যার এবং সফ্টওয়্যার ত্রুটিগুলি নিঃসন্দেহে ইউইউডি সদৃশ সমস্যার তুলনায় কয়েক হাজার গুণ বেশি ঘন ঘন হবে। প্রতি সেকেন্ডে 1 গিগাবিট স্থানান্তর হারের জন্য একটি একক প্রসেসরের জন্য 3000 বছরের বেশি সময় লাগবে। যেহেতু ড্রাইভের অপরিবর্তনযোগ্য পঠন ত্রুটির হার 1018 বিট পড়লে প্রতি 1 বিট হয় তবে সর্বোপরি, যখন ফাইলটি প্রায় 1020 বিট ধারণ করে, কেবল একবার ফাইলটি প্রান্ত থেকে শেষ পর্যন্ত পড়ার ফলে কমপক্ষে প্রায় 100 গুণ বেশি ভুল- সদৃশগুলির চেয়ে ইউআইডি পড়ুন। স্টোরেজ, নেটওয়ার্ক, শক্তি এবং অন্যান্য হার্ডওয়্যার এবং সফ্টওয়্যার ত্রুটিগুলি নিঃসন্দেহে ইউইউডি সদৃশ সমস্যার তুলনায় কয়েক হাজার গুণ বেশি ঘন ঘন হবে।

উত্স: উইকিপিডিয়া

সংক্ষেপে,

  • ইউআইডি মানক করা হয়।
  • gen_random_uuid()এলোমেলো 128 বিট 128 বিট (2 ** 128 সংমিশ্রণে) সঞ্চিত হয়। 0-বর্জ্য।
  • random() পোস্টগ্র্রেএসকিউএল এ কেবল 52 বিট র্যান্ডম উত্পন্ন করে (2 ** 52 সংমিশ্রণ)।
  • md5()ইউআইডি হিসাবে সঞ্চিত 128 বিট, তবে এটি কেবল তার ইনপুটের মতো এলোমেলো হতে পারে ( যদি ব্যবহার করা হয় তবে 52 বিটrandom() )
  • md5()পাঠ্য হিসাবে সঞ্চিত 288 বিট, তবে এটি কেবলমাত্র তার ইনপুট ( 52 টি বিট ব্যবহার করা হলেrandom() ) - কোনও ইউইউডি এর আকার এবং এলোমেলোতার একটি ভগ্নাংশের দ্বিগুণের বেশি হতে পারে rand
  • md5() হ্যাশ হিসাবে, এটি এতটা অনুকূলিত করা যেতে পারে যে এটি কার্যকরভাবে বেশি কিছু করতে পারে না।
  • ইউআইডি স্টোরেজের জন্য অত্যন্ত দক্ষ: পোস্টগ্রিসএসকিউএল এমন এক প্রকার সরবরাহ করে যা হুবহু 128 বিট। ভিন্ন textএবং varcharইত্যাদি, যা varlenaস্ট্রিংয়ের দৈর্ঘ্যের জন্য ওভারহেড রয়েছে এমন হিসাবে সঞ্চয় করে ।
  • পোস্টগ্রিসএসকিউএল নিফটি ইউআইডিটি কিছু ডিফল্ট অপারেটর, castালাই এবং বৈশিষ্ট্যগুলির সাথে আসে।

4
আংশিকভাবে ভুল: একটি যথাযথ উত্পন্ন র্যান্ডম ইউআইডি-তে কেবল 122 র্যান্ডম বিট রয়েছে কারণ 4 বিট সংস্করণের জন্য এবং 2 বিট ভেরিয়েন্টের জন্য ব্যবহৃত হয়: en.wikedia.org/wiki/…
অলিভিয়ের

4
উত্স যদি সেখানে লেখা আছে তা না করে তবে এটি কোনও ইউইউডি নয় এবং পোস্টগ্র্রেএসকিউএল দ্বারা কল করা উচিত নয়।
অলিভিয়ার

16

আমি সম্প্রতি পোস্টগ্রেএসকিউএল এর সাথে খেলছিলাম এবং আমি মনে করি আমি কেবল বিল্ট-ইন পোস্টগ্র্রেএসকিউএল পদ্ধতি ব্যবহার করে কিছুটা ভাল সমাধান পেয়েছি - কোন পিএল / পিএসএসকিএল। শুধুমাত্র সীমাবদ্ধতা হ'ল এটি বর্তমানে কেবলমাত্র ইউপিসিএসই স্ট্রিং, বা সংখ্যা বা লোয়ার কেস স্ট্রিং উত্পন্ন করে।

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পদ্ধতির দ্বিতীয় যুক্তি স্ট্রিংয়ের দৈর্ঘ্য নির্ধারণ করে।


8
আমি এটি পছন্দ করি, কিন্তু যখন আমি এটি একটি আপডেটের বিবৃতি ব্যবহার করি, তখন সমস্ত সারি অনন্য পাসওয়ার্ডের পরিবর্তে একই র্যান্ডম পাসওয়ার্ডে সেট করা হয়েছিল। সূত্রটিতে প্রাথমিক কী আইডি যুক্ত করে আমি এটি সমাধান করেছি। আমি এটিকে এলোমেলো মানতে যুক্ত করব এবং এটি আবার বিয়োগ করুন। এলোমেলোভাবে পরিবর্তন করা হয় নি, তবে পোস্টগ্রেএসকিউএল প্রতিটি সারির জন্য মানগুলি পুনরায় গণনা করার জন্য ট্রিক করা হয়। "মাই_আইডি" এর প্রাথমিক কী নামটি ব্যবহার করে এখানে একটি উদাহরণ দেওয়া হয়েছে: 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)), '');
নুনো রাফায়েল

4
না, আপনি উত্তর দিচ্ছেন 'আমি কীভাবে এলোমেলো সেশন আইডি উত্পন্ন করব ' তা নয়, 'আমি কীভাবে এলোমেলো স্ট্রিং উত্পন্ন করব '। বর্ণনার দুটি শব্দের ভিত্তিতে আপনি কুইকিটনের অর্থ (এবং শিরোনাম) পরিবর্তন করেছেন। আপনি বিভিন্ন প্রশ্নের উত্তর দিচ্ছেন। এবং প্রশ্নটির অর্থ পরিবর্তনের জন্য আপনার সংযম ক্ষমতাটিকে অপব্যবহার করে চলেছেন।
মার্সিন র্যাকজকোভস্কি

14

দয়া করে ব্যবহার করুন string_agg!

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

আমি এটি ইউডিউডি তৈরির জন্য এমডি 5 দিয়ে ব্যবহার করছি। আমি কেবল একটি random ()পূর্ণসংখ্যার চেয়ে বেশি বিট সহ একটি এলোমেলো মান চাই ।


আমি মনে করি আমি যতটা random()বিট চাই তার সংখ্যা না পাওয়া পর্যন্ত আমি কেবল কনটেনেট করতে পারি। আচ্ছা ভালো.
অ্যান্ড্রু ওল্ফ

11

ডিফল্টরূপে সক্রিয় না থাকা অবস্থায় আপনি মূল এক্সটেনশনের একটি সক্রিয় করতে পারেন:

CREATE EXTENSION IF NOT EXISTS pgcrypto;

তারপরে আপনার বক্তব্য জেন_সাল্ট () এ একটি সাধারণ কল হয়ে যায় যা একটি এলোমেলো স্ট্রিং উত্পন্ন করে:

select gen_salt('md5') from generate_series(1,4);

 gen_salt
-----------
$1$M.QRlF4U
$1$cv7bNJDM
$1$av34779p
$1$ZQkrCXHD

শীর্ষস্থানীয় নম্বর হ্যাশ শনাক্তকারী। বেশ কয়েকটি অ্যালগরিদম তাদের নিজস্ব সনাক্তকারী সাথে উপলব্ধ:

  • এমডি 5: $ 1 $
  • bf: $ 2a $ 06 $
  • des: কোনও সনাক্তকারী নয়
  • xdes: _J9 ..

এক্সটেনশন সম্পর্কিত আরও তথ্য:


সম্পাদনা

ইভান ক্যারল দ্বারা নির্দেশিত হিসাবে, v9.4 হিসাবে আপনি ব্যবহার করতে পারেন gen_random_uuid()

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


উত্পন্ন উত্সগুলি সত্যই এলোমেলোভাবে অনুক্রমিক মনে হয়, তাই না?
লে ড্রয়েড

4
আপনি কি উল্লেখ করছেন $1$? এটি হ্যাশ প্রকারের শনাক্তকারী (এমডি 5 == 1), বাকিটি এলোমেলো মান।
জেফেরি কেভ

হ্যাঁ, এটি আমার ভুল ব্যাখ্যা ছিল, নির্ভুলতার জন্য ধন্যবাদ।
লে ড্রয়েড

6

আমি মনে করি না যে আপনি প্রতি সেমি এলোমেলো স্ট্রিং খুঁজছেন। সেশন যাচাইকরণের জন্য আপনার যা প্রয়োজন তা হ'ল একটি স্ট্রিং যা অনন্য হওয়ার গ্যারান্টিযুক্ত। আপনি কি অডিটের জন্য সেশন যাচাইকরণ তথ্য সংরক্ষণ করেন? সেক্ষেত্রে আপনার স্ট্রিংটি সেশনের মধ্যে অনন্য হতে হবে। আমি দুটি, বরং সহজ পদ্ধতির সম্পর্কে জানি:

  1. একটি ক্রম ব্যবহার করুন। একক ডাটাবেসে ব্যবহারের জন্য ভাল।
  2. একটি ইউইউডি ব্যবহার করুন। সর্বজনীনভাবে অনন্য, বিতরণ করা পরিবেশেও তাই ভাল।

ইউআইডিগুলি প্রজন্মের জন্য তাদের অ্যালগোরিদমের গুণাবলী অনুসারে অনন্য হওয়ার গ্যারান্টিযুক্ত ; কার্যকরভাবে এটা অত্যন্ত অসম্ভাব্য যে আপনি কোনো মেশিনে একই রকম দুটি সংখ্যার তৈরি করবে, যে কোন সময়ে, কখনও (নোট যে এই র্যান্ডম স্ট্রিং, যা UUID জানা চেয়ে অনেক ছোটো আকারের পর্যাবৃত্তি উপর তুলনায় অনেক শক্তিশালী)।

ইউআইডি ব্যবহার করতে আপনাকে uuid-ossp এক্সটেনশন লোড করতে হবে। একবার ইনস্টল হয়ে গেলে, আপনার নির্বাচন, INSERT বা আপডেট আপডেটগুলিতে উপলব্ধ যে কোনও uuid_generate_vXXX () ফাংশনটিতে কল করুন। ইউইড টাইপটি একটি 16-বাইট সংখ্যা, তবে এটির স্ট্রিং প্রতিনিধিত্বও রয়েছে।


এটি সম্ভবত বিপজ্জনক পরামর্শ মত মনে হচ্ছে। যখন সেশন কীগুলির কথা আসে, আপনি স্বতন্ত্রতা এবং এলোমেলোতা চান যা ক্রিপ্টোগ্রাফিকভাবে যথেষ্ট এলোমেলো যাতে এটি অনুমান করার কোনও যুক্তিসঙ্গত সুযোগকে বাদ দিতে পারে। ইউআইডি দ্বারা ব্যবহৃত অ্যালগরিদমগুলি এলোমেলো (বেশিরভাগ) মেকানিজম দ্বারা স্বতন্ত্রতার গ্যারান্টি দেয়, যা সুরক্ষার জন্য হুমকিস্বরূপ।
jmar777

6
@ jmar777 ইউআইডি গুলোর পুরো উদ্দেশ্য হ'ল এগুলি অনুমান করা কঠিন এবং অত্যন্ত এলোমেলো। ভি 1 সংস্করণ ব্যতীত তাদের খুব উচ্চ পর্যায়ক্রমিকতা রয়েছে; v4 সম্পূর্ণ 128-বিট এলোমেলো। এগুলি আপনার করা প্রতিটি অনলাইন ব্যাংকিং লেনদেনে ব্যবহৃত হচ্ছে। যদি তারা এর জন্য যথেষ্ট ভাল হয় তবে তারা অন্য যে কোনও কিছুর জন্য যথেষ্ট যথেষ্ট।
প্যাট্রিক

4
ভাল, তুমি কি জানো. আমি বুঝতে পারিনি যে সংস্করণ 4 এ সম্বোধন করা হয়েছিল । আমাকে সংশোধন করার জন্য ধন্যবাদ!
jmar777

@ পেট্রিক ছোট্ট নিট, ভি 4 ইউআইডিগুলি 122 বিট এলোমেলো, 128 নয়;);
জেসি

5

INTEGER পরামিতি স্ট্রিংয়ের দৈর্ঘ্য নির্ধারণ করে। সমান সম্ভাবনা (সমস্ত ইন্টারনেটে ভাসমান কিছু অন্যান্য সমাধানের বিপরীতে) সমস্ত al২ টি আলফানাম অক্ষর কভার করার গ্যারান্টিযুক্ত।

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;

ধীরে ধীরে, এলোমেলো নয় বা সঞ্চয় করার মতো দক্ষ নয়। সেশন আইডসের জন্য খুব ভাল সমাধান নয়, খুব বেশি এলোমেলো নয়। উত্তরটিও 6 বছরের পুরানো। Check out this for a totally different method using gen_random_uuid(): দ্রুত, আরও এলোমেলোতা, আরও দক্ষতার সাথে ডাটাবেসে সঞ্চিত।
ইভান ক্যারল

4
@ ইভানক্রোল: সমস্ত ন্যায্যতায়, gen_random_uuid()সংস্করণ 9.4 এ উপস্থিত হয়েছে যতদূর আমি বলতে পারি, যা 2014-12-18 প্রকাশিত হয়েছিল, উত্তরটি আপনার চেয়ে কম উত্তর দেওয়ার এক বছরেরও বেশি সময় পরে প্রকাশিত হয়েছিল। অতিরিক্ত নিটপিক: উত্তরটি মাত্র 3/2 বছর বয়সী :-) তবে আপনি ঠিক বলেছেন এখন আমাদের কাছে রয়েছে gen_random_uuid()এটি ব্যবহার করা উচিত। সুতরাং আমি আপনার উত্তর upvote করব।
ল্যারিক্স ডিসিদুয়া

5

@ কভিয়াস ব্যবহারের প্রস্তাব দিয়েছিলেন pgcrypto, তবে পরিবর্তে gen_salt, কী gen_random_bytes? এবং sha512পরিবর্তে কিভাবে md5?

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

দস্তাবেজ:

F.25.5। এলোমেলো-ডেটা ফাংশন

gen_random_bytes (গণনা পূর্ণসংখ্যার) বাইটায় ফেরত দেয়

ক্রিপ্টোগ্রাফিকভাবে শক্তিশালী এলোমেলো বাইটগুলি গণনা দেয়। একসাথে সর্বাধিক 1024 বাইট বের করা যেতে পারে। এটি র্যান্ডমনেস জেনারেটর পুলটি নিষ্কাশন করা এড়ানোর জন্য।


আমি ভাবছি যে sha512আপনি হ্যাশ করছেন অন্তর্নিহিত ডেটা এলোমেলো যদি অফারগুলি কোনও সুবিধা দেয় কিনা offers এলোমেলোতা ধরে নিলে, স্ট্রিংটিতে এনকোড করা যে কোনও কিছুই পর্যাপ্ত পরিমাণে হওয়া উচিত, এবং কম কম্পিউটেশনাল জটিল, আরও ভাল (যেমন। বেস 64 এনকোডিং?)। - দুঃখিত, পুরানো মন্তব্য, কিন্তু কাজের কারও সাথে আলোচনা করার সময় এসেছিল
জেফেরি কেভ

@ জেফেরে কেভ কেটে গেছে 6 বছর, সুতরাং আমি প্রসঙ্গটি মনে রাখছি না তবে দেখে মনে হচ্ছে যে ওপি সেশন আইডির বিষয়ে জিজ্ঞাসা করছে , এবং sha512এর চেয়ে 4 গুণ বেশি লম্বা হওয়ার সুবিধা থাকবে md5এবং এইভাবে সংঘর্ষের আক্রমণ আরও কঠিন হবে?
জ্যারেড বেক

আমি সম্মত হলাম যে আরও দীর্ঘতর ... আমি ভাবছিলাম যে আপনার উত্তরটি সম্পূর্ণ ছিল select gen_random_bytes(1024).. এবং হ্যাঁ ... 6 বছর। সহকর্মীর সাথে খুব স্বেচ্ছাসেবী কথোপকথন এটি সামনে এনেছিল।
জেফারি গুহ


2
select encode(decode(md5(random()::text), 'hex')||decode(md5(random()::text), 'hex'), 'base64')

আমি ফরোয়ার্ড-স্ল্যাশ এবং প্লাস চিহ্নটি মুছে ফেলার জন্য এটি সংশোধন করি যা কখনও কখনও ফলাফলের মধ্যে উপস্থিত হয় এবং একটি বড় আকারের ফলাফল উত্পন্ন করতেও উপরেরটি নির্বাচন করুন (প্রতিস্থাপন করুন (সাবস্ট্রিং (এনকোড (এমডি 5 (র্যান্ডম () :: পাঠ্য)), 'হেক্স ') || ডিকোড (এমডি 5 (এলোমেলো () :: পাঠ্য),' হেক্স '),' বেস 64 '), 0, 10),' / ',' এ '),' + ',' জেড '));
Seun ম্যাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.