दिलचस्प पोस्ट
क्या रेजर सिंटैक्स UI मार्कअप में एक सम्मोहक लाभ प्रदान करता है? जब मैं पहली बार एक दृश्य को माप सकता हूँ? Django- पंजीकरण और Django- प्रोफाइल, अपने खुद के कस्टम प्रपत्र का उपयोग कर PHP में दिए गए कुंजी के मान द्वारा एसोसिएटिव एरे की एक सरणी कैसे सॉर्ट करनी है? WPF विंडो शैली को लागू नहीं किया जा रहा है स्विफ्ट: फ़िल्टर शब्दकोश स्प्रिंग एमवीसी में @ModelAttribute क्या है? एप प्रकाशित करते समय ज़िप-संरेखण नहीं मिल सकता WPF C # बटन शैली Launch4j के साथ एक JRE बंडल करने के लिए कैसे? प्रतिबद्ध करने से पहले 'git add' को कैसे पूर्ववत करें? यदि वह मौजूद है तो पंक्ति को अपडेट करें या फिर इकाई फ़्रेमवर्क के साथ डालें तर्क अनेक स्ट्रिंग के विकल्प। पुनर्स्थापन एंड्रॉइड में सभी अक्षर को प्रदर्शित करने के लिए एक वर्णानुक्रमिक स्क्रॉलबार कैसे बनाएं? मोजररा जेएसएफ में फ्लैश के बारे में अपवाद

MySQL का उपयोग करते हुए एक यादृच्छिक और अद्वितीय 8 वर्ण स्ट्रिंग उत्पन्न करना

मैं एक गेम पर काम कर रहा हूं जिसमें कुछ बिंदुओं पर वाहन शामिल हैं I मेरे पास वाहनों के बारे में डेटा युक्त "वाहन" नामक एक MySQL तालिका है, जिसमें स्तंभ "प्लेट" शामिल है, जो वाहनों के लिए लाइसेंस प्लेट्स को स्टोर करता है।

अब यहाँ हिस्सा आता है जिसके साथ मुझे समस्या आ रही है। मुझे एक नया वाहन बनाने से पहले एक अप्रयुक्त लाइसेंस प्लेट खोजने की आवश्यकता है – यह एक अल्फ़ान्यूमेरिक 8-वर्ण यादृच्छिक स्ट्रिंग होना चाहिए। मैं यह कैसे हासिल कर रहा हूं, लिआ में थोड़ी देर लूप का उपयोग कर रहा था, जो कि मैं प्रोग्रामिंग कर रहा हूँ, तार उत्पन्न करने और डीबी को यह देखने के लिए कि क्या इसका इस्तेमाल होता है, भाषा है। हालांकि, जैसा कि वाहनों की संख्या बढ़ जाती है, मुझे उम्मीद है कि यह अभी और अधिक अक्षम नहीं हो सके, यह अभी ठीक है। इसलिए, मैंने एक MySQL क्वेरी का उपयोग करके इस समस्या का प्रयास करने और उसे सुलझाने का निर्णय लिया।

मुझे जिस क्वेरी की आवश्यकता है, वह सिर्फ 8-वर्ण अल्फ़ान्यूमेरिक स्ट्रिंग उत्पन्न करेगी जो पहले से तालिका में नहीं है। मैंने फिर से उत्पन्न पाश और जांच के बारे में सोचा, लेकिन मैं इस प्रश्न को सीमित नहीं कर रहा हूं, सिर्फ इसलिए कि कोई और अधिक कुशल एक है मैं स्ट्रिंग्स को सभी अक्षरों को परिभाषित करके स्ट्रिंग्स उत्पन्न करने में सक्षम बना रहा हूं और बेतरतीब ढंग से इसे सबस्ट्रिंग कर रहा है, और कुछ और नहीं।

किसी भी मदद की सराहना की है

Solutions Collecting From Web of "MySQL का उपयोग करते हुए एक यादृच्छिक और अद्वितीय 8 वर्ण स्ट्रिंग उत्पन्न करना"

इस समस्या में दो बहुत अलग उप समस्याएं हैं:

  • स्ट्रिंग प्रतीत होता है यादृच्छिक होना चाहिए
  • स्ट्रिंग अद्वितीय होना चाहिए

जबकि यादृच्छिकता काफी आसानी से हासिल की जाती है, फिर भी कोई प्रयास किए बिना लचीलापन की विशिष्टता नहीं है। यह हमें विशिष्टता पर ध्यान केंद्रित करने के लिए पहले लाता है। गैर-यादृच्छिक विशिष्टता AUTO_INCREMENT साथ तुच्छ हो सकती है तो एक विशिष्टता-संरक्षण का उपयोग करके, छद्म यादृच्छिक परिवर्तन ठीक होगा:

  • हैश @ पॉल द्वारा सुझाव दिया गया है
  • एईएस-एन्क्रिप्ट भी फिट बैठता है
  • लेकिन एक अच्छा एक है: RAND(N) ही!

एक ही बीज के द्वारा बनाई गई यादृच्छिक संख्या का एक क्रम होने की गारंटी है

  • प्रतिलिपि प्रस्तुत करने योग्य
  • पहले 8 पुनरावृत्तियों के लिए अलग
  • अगर बीज एक INT32 है

इसलिए हम @ एंड्रीवॉल्क या @ गॉर्डन लीनॉफ के दृष्टिकोण का उपयोग करते हैं, लेकिन एक बीजांकित RAND :

उदाहरण के लिए एसड्यूमिन id एक एटऑन्ग्रेमेंट कॉल है:

 INSERT INTO vehicles VALUES (blah); -- leaving out the number plate SELECT @lid:=LAST_INSERT_ID(); UPDATE vehicles SET numberplate=concat( substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@lid)*4294967296))*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed:=round(rand(@seed)*4294967296))*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand(@seed)*36+1, 1) ) WHERE id=@lid; 

जैसा कि मैंने अपनी टिप्पणी में कहा था, मैं टक्कर की संभावना के साथ परेशान नहीं था बस एक यादृच्छिक स्ट्रिंग उत्पन्न करें और जांचें कि क्या यह मौजूद है। यदि ऐसा होता है, तो फिर से प्रयास करें और आपको इसके लिए कुछ और बार ऐसा करने की आवश्यकता नहीं होनी चाहिए, जब तक आपके पास पहले से ही सौंपी गई बड़ी संख्या में प्लेट नहीं है।

शुद्ध (माय) एसक्यूएल में एक 8-वर्ण लंबे छद्म-यादृच्छिक स्ट्रिंग उत्पन्न करने के लिए एक अन्य समाधान:

 SELECT LEFT(UUID(), 8); 

आप निम्न (छद्म कोड) की कोशिश कर सकते हैं:

 DO SELECT LEFT(UUID(), 8) INTO @plate; INSERT INTO plates (@plate); WHILE there_is_a_unique_constraint_violation -- @plate is your newly assigned plate number 

अनुक्रमिक पूर्णांक के एमडी 5 (या अन्य) हश की गणना के बारे में, फिर पहले 8 अक्षर लेते हैं।

अर्थात

 MD5(1) = c4ca4238a0b923820dcc509a6f75849b => c4ca4238 MD5(2) = c81e728d9d4c2f636f067f89cc14862c => c81e728d MD5(3) = eccbc87e4b5ce2fe28308fd9f2a7baf3 => eccbc87e 

आदि।

चेतावनी: मुझे पता नहीं है कि आप कितने टकराव से पहले आवंटित कर सकते हैं (लेकिन यह ज्ञात और स्थिर मूल्य होगा)।

संपादित करें: यह अब एक पुराना उत्तर है, लेकिन मैंने अपने हाथों पर इसे फिर से देखा, अतः, अवलोकन से …

सभी संख्याओं की संभावना = 2.35%

सभी पत्रों की संभावना = 0.05%

पहली टक्कर जब एमडी 5 (82945) = "7b763dcb …" (उसी परिणाम के रूप में MD5 (25302))

यहां एक तरीका है, अल्फ़ा संख्याओं का उपयोग वैध वर्णों के रूप में:

 select concat(substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1), substring('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', rand()*36+1, 1) ) as LicensePlaceNumber; 

ध्यान दें विशिष्टता की कोई गारंटी नहीं है आपको इसके लिए अलग से जांच करना होगा

आप MySQL के रैंड () और चार () फ़ंक्शन का उपयोग कर सकते हैं:

 select concat( char(round(rand()*25)+97), char(round(rand()*25)+97), char(round(rand()*25)+97), char(round(rand()*25)+97), char(round(rand()*25)+97), char(round(rand()*25)+97), char(round(rand()*25)+97), char(round(rand()*25)+97) ) as name; 

एक यादृच्छिक स्ट्रिंग बनाएं

दी गई लंबाई का एक यादृच्छिक स्ट्रिंग बनाने के लिए यहां एक MySQL फ़ंक्शन है I

 DELIMITER $$ CREATE DEFINER=`root`@`%` FUNCTION `RandString`(length SMALLINT(3)) RETURNS varchar(100) CHARSET utf8 begin SET @returnStr = ''; SET @allowedChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; SET @i = 0; WHILE (@i < length) DO SET @returnStr = CONCAT(@returnStr, substring(@allowedChars, FLOOR(RAND() * LENGTH(@allowedChars) + 1), 1)); SET @i = @i + 1; END WHILE; RETURN @returnStr; END 

एक 8 वर्ण स्ट्रिंग वापस करने के लिए उपयोग SELECT RANDSTRING(8)

आप @allowedChars को अनुकूलित कर सकते हैं।

विशिष्टता की गारंटी नहीं है – जैसा कि आप अन्य समाधानों पर टिप्पणियों में देखेंगे, यह संभव नहीं है। इसके बजाय आपको एक स्ट्रिंग उत्पन्न करने की आवश्यकता होगी, जांच लें कि यह पहले से उपयोग में है, और फिर कोशिश करें अगर यह है।


जांचें कि बेतरतीब स्ट्रिंग पहले ही उपयोग में है या नहीं

अगर हम एप के टकराव जांच कोड को रखना चाहते हैं, तो हम एक ट्रिगर बना सकते हैं:

 DELIMITER $$ CREATE TRIGGER Vehicle_beforeInsert BEFORE INSERT ON `Vehicle` FOR EACH ROW BEGIN SET @vehicleId = 1; WHILE (@vehicleId IS NOT NULL) DO SET NEW.plate = RANDSTRING(8); SET @vehicleId = (SELECT id FROM `Vehicle` WHERE `plate` = NEW.plate); END WHILE; END;$$ DELIMITER ; 

आप निम्न के साथ एक यादृच्छिक अक्षरांकीय स्ट्रिंग उत्पन्न कर सकते हैं:

 lpad(conv(floor(rand()*pow(36,8)), 10, 36), 8, 0); 

आप इसे BEFORE INSERT ट्रिगर BEFORE INSERT उपयोग कर सकते हैं और एक लूप में डुप्लिकेट की जांच कर सकते हैं:

 CREATE TABLE `vehicles` ( `plate` CHAR(8) NULL DEFAULT NULL, `data` VARCHAR(50) NOT NULL, UNIQUE INDEX `plate` (`plate`) ); DELIMITER // CREATE TRIGGER `vehicles_before_insert` BEFORE INSERT ON `vehicles` FOR EACH ROW BEGIN declare str_len int default 8; declare ready int default 0; declare rnd_str text; while not ready do set rnd_str := lpad(conv(floor(rand()*pow(36,str_len)), 10, 36), str_len, 0); if not exists (select * from vehicles where plate = rnd_str) then set new.plate = rnd_str; set ready := 1; end if; end while; END// DELIMITER ; 

अब बस अपना डेटा डालें

 insert into vehicles(col1, col2) values ('value1', 'value2'); 

और ट्रिगर plate कॉलम के लिए एक मूल्य उत्पन्न करेगा।

( sqlfiddle डेमो )

यह इस तरह से काम करता है अगर कॉलम नाउल्स की अनुमति देता है यदि आप चाहते हैं कि यह नल न हो तो आपको एक डिफ़ॉल्ट मान को परिभाषित करने की आवश्यकता होगी

 `plate` CHAR(8) NOT NULL DEFAULT 'default', 

आप ट्रिगर में किसी भी अन्य यादृच्छिक स्ट्रिंग पैदा करने वाले एल्गोरिथ्म का उपयोग कर सकते हैं यदि ऊपरी अक्षर अल्फ़ान्यूमिक्स आप नहीं चाहते हैं। लेकिन ट्रिगर अद्वितीयता का ख्याल रखना होगा।

मैं "हैश" या अद्वितीय स्ट्रिंग उत्पन्न करने के लिए किसी दूसरे कॉलम से डेटा का उपयोग कर रहा हूं I

 UPDATE table_name SET column_name = Right( MD5(another_column_with_data), 8 ) 

यदि आप "यादृच्छिक" लेकिन पूरी तरह से उम्मीद के मुताबिक लाइसेंस प्लेटों के साथ ठीक हैं, तो आप अगले प्लेट नंबर को चुनने के लिए रैखिक-प्रतिक्रिया बदलाव रजिस्टर का उपयोग कर सकते हैं – दोहराए जाने से पहले प्रत्येक संख्या में जाने की गारंटी है। हालांकि, कुछ जटिल गणित के बिना, आप प्रत्येक 8 अक्षर अल्फ़ान्यूमेरिक स्ट्रिंग के माध्यम से नहीं जा सकेंगे (आपको संभवतः 36 ^ 8 (78%) संभावित प्लेटों में से 2 ^ 41 मिलेगा)। इसे अपने स्थान को बेहतर बनाने के लिए, आप प्लेट्स (शायद हे) से एक पत्र को बाहर कर सकते हैं, जिससे आप 97% दे सकते हैं।

खाते में कुल अक्षरों की संख्या को ध्यान में रखते हुए, जिनकी आपको आवश्यकता होती है, आपके पास दो बिल्कुल समान नंबर प्लेट उत्पन्न करने का एक बहुत छोटा मौका होता। इस प्रकार आप शायद LUA में संख्याएं पैदा करने के साथ भाग ले सकते हैं।

आपके पास 36 ^ 8 अद्वितीय अनन्य संख्याएं (2,821,10 9, 9 07,456, यह बहुत कुछ है), भले ही आपके पास पहले से ही एक मिलियन संख्याएं हैं, तो आपके पास पहले से ही पैदा होने वाले एक को पैदा करने का एक छोटा सा मौका होता है, लगभग 0.000035%

बेशक, यह सब कितने numberplates पर निर्भर करता है आप का निर्माण खत्म हो जाएगा।

वर्णमाला से 8 अक्षर – सभी कैप्स:

 UPDATE `tablename` SET `tablename`.`randomstring`= concat(CHAR(FLOOR(65 + (RAND() * 25))),CHAR(FLOOR(65 + (RAND() * 25))),CHAR(FLOOR(65 + (RAND() * 25))),CHAR(FLOOR(65 + (RAND() * 25)))CHAR(FLOOR(65 + (RAND() * 25))),CHAR(FLOOR(65 + (RAND() * 25))),CHAR(FLOOR(65 + (RAND() * 25))),CHAR(FLOOR(65 + (RAND() * 25)))); 

एक स्ट्रिंग के लिए जिसमें 8 रैंडम संख्याएं और ऊपरी और छोटे अक्षर शामिल हैं, यह मेरा समाधान है:

 LPAD(LEFT(REPLACE(REPLACE(REPLACE(TO_BASE64(UNHEX(MD5(RAND()))), "/", ""), "+", ""), "=", ""), 8), 8, 0) 

अंदर से समझाया गया:

  1. RAND 0 और 1 के बीच यादृच्छिक संख्या उत्पन्न करता है
  2. MD5 (1) के एमडी 5 योग की गणना करता है, वायुसेना से 32 वर्ण और 0- 9
  3. UNHEX अनुवाद (2) 16 बाइट्स में 00 से एफएफ के मूल्यों के साथ
  4. TO_BASE64 एन्कोड (3) बेस64 के रूप में, एज़ और एजेड से 22 वर्ण और 0-9 प्लस "/" और "+", दो "="
  5. तीन जगहों से "/", "+" और "=" वर्णों को हटा दें (4)
  6. LEFT पहले (5) से 8 अक्षर लेता है, 8 को कुछ और बदलें यदि आपको अपने यादृच्छिक स्ट्रिंग में अधिक या कम वर्ण की आवश्यकता है
  7. LPAD (6) की शुरूआत में शून्य को सम्मिलित करता है यदि यह 8 वर्णों से कम है; फिर से, अगर जरूरत पड़ने पर कुछ और 8 को बदल दें

यदि आपके पास आईडी या बीज नहीं है, तो इसकी सम्मिलित सूची में मान सूची के लिए:

 REPLACE(RAND(), '.', '')