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


110

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

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

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

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


आपको इनकी कितनी यादृच्छिक आवश्यकता है? यदि कोई व्यक्ति किसी विशेष लाइसेंस प्लेट को प्राप्त करता है, तो क्या यह महत्वपूर्ण है या नहीं कि वे आपके द्वारा सौंपे गए अगले या पिछले लाइसेंस प्लेट को काम कर सकते हैं या नहीं?
Damien_The_Unbeliever

@YaK टकराव की छोटी संभावना से बचने के बारे में मेरा जवाब देखें
यूजेन रीक

जवाबों:


87

इस समस्या में दो बहुत भिन्न उप-समस्याएं शामिल हैं:

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

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

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

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

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

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

उदाहरण के लिए Assumin idएक AUTO_INCREMENTकॉलम है:

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;

बहुत अंतःक्रियात्मक दृष्टिकोण, लेकिन आप शायद मतलब था RAND(LAST_INSERT_ID()); UPDATE vehicles (...) , rand()*36+1, (...)(या यह एक ही चरित्र से 8 गुना रिटर्न देता है)। हम कैसे सुनिश्चित कर सकते हैं कि 8 क्रमिक कॉल को rand()एक अलग सीड के साथ इनिशियलाइज़ किए जाने पर एक अलग सीक्वेंस वापस करने की गारंटी दी जाए?
रैंडमसाइड

8
मैं बस सोच रहा था। आप उन नंबरों का उपयोग क्यों करते हैं .. 4294967296)) * 36 + 1?
मिक

7
यह थोड़ा पुराना है, लेकिन मैं यह नोट करना चाहूंगा कि मुझे FLOOR()दूसरे प्रतिस्थापन मानकों के आसपास जोड़ना पड़ा : substring('ABC … 789', floor(rand(@seed:= … )*36+1), 1), कुछ अवसरों पर, विकल्प 36.9 वर्ण को चुनने की कोशिश कर रहा था, जो 37 तक गोल होने पर, कोई वर्ण नहीं चुने जाने के परिणामस्वरूप होगा।
फिलिप डोडसन

4
यदि यह प्रतिलिपि प्रस्तुत करने योग्य नहीं है, तो आप किसी स्ट्रिंग को यादृच्छिक नहीं कह सकते। और डुप्लिकेट भी संभव हैं, क्योंकि आप उपयोग कर रहे हैं floor()। यह sqlfiddle दिखाता है, कि डुप्लिकेट तीन वर्ण लंबे तार के लिए बनाए जाते हैं।
पॉल स्पीगेल

6
@EugenRieck मुझे समझ में नहीं आता है कि आपको अपने नंबर कैसे मिलते हैं ("पहले 2 ^ 32 पुनरावृत्तियों")। लेकिन मुझे इस अवधारणा को खंडित करने के लिए डुप्लिकेट का केवल एक उदाहरण चाहिए। आईडी 193844और 775771आपके एल्गोरिथ्म के लिए एक ही स्ट्रिंग T82X711( डेमो ) उत्पन्न करेगा ।
पॉल स्पीगेल

113

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

शुद्ध (मेरा) एसक्यूएल में 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

चूँकि इस पोस्ट ने अप्रत्याशित स्तर पर ध्यान आकर्षित किया है, मुझे ADTC की टिप्पणी पर प्रकाश डालने दो : कोड का उपरोक्त टुकड़ा काफी गूंगा है और अनुक्रमिक अंक पैदा करता है।

थोड़े कम बेवकूफ यादृच्छिकता के लिए इसके बजाय कुछ इस तरह की कोशिश करें:

SELECT LEFT(MD5(RAND()), 8)

और सच (क्रिप्टोग्रापिक रूप से सुरक्षित) यादृच्छिकता के RANDOM_BYTES()बजाय, RAND()(लेकिन तब मैं इस तर्क को एप्लिकेशन परत तक ले जाने पर विचार करूंगा)।


आपके समाधान के लिए धन्यवाद, मेरे पास UUID के संबंध में एक प्रश्न है। आप 8 कैरेक्टर को बनाने की आईडी को कितने रिपीट करते हैं।
टीआर-अहमद

1
@ user3099183 आधिकारिक तौर पर , "बहुत कम"। 16 ^ 8 के बारे में 4 अरब संभव तार है।
रैंडमसाइड

23
कृपया ध्यान दें कि UUID के पहले 8 अक्षर यादृच्छिक नहीं हैं, लेकिन अनुक्रमिक हैं, क्योंकि यह टाइमस्टैम्प पर आधारित है।
ADTC

मैं 9-वर्ण लंबी यादृच्छिक स्ट्रिंग उत्पन्न करना चाहता हूं, और जब मैं 9आपके कोड का उपयोग करता हूं SELECT LEFT(UUID(), 9);, तो हमेशा -उत्पन्न स्ट्रिंग के अंत में नौवें चरित्र के रूप में होता है। यह स्थिर है। क्यों?
मार्टिन ए जे

3
@MartinAJ क्योंकि स्ट्रिंग एक uuid है । आप आसानी से हाइफ़न जैसे जगह ले सकता हैSELECT LEFT(REPLACE(UUID(), '-', ''), 16);
jchook

53

अनुक्रमिक पूर्णांक के MD5 (या अन्य) हैश की गणना के बारे में क्या, फिर पहले 8 वर्णों को लेना।

अर्थात

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

आदि।

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

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

सभी नंबरों की संभावना = 2.35%

सभी अक्षरों की संभावना = 0.05%

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


2
अच्छा विचार, प्राथमिक कुंजी पर इसका उपयोग कर सकता है। भविष्य की परियोजनाओं के लिए इसे ध्यान में रखेंगे, धन्यवाद!
फनस्टीन

2
एक मौका है कि यह केवल नंबरों के साथ परिणाम कर सकता है
म्लाडेन Janjetovic

9
यह यादृच्छिक नहीं है।
पौल

1
यदि आप ऑटो वृद्धिशील आईडी का उपयोग करने के बजाय इसे अधिक "यादृच्छिक" बना सकते हैं, तो आप उस डाइमटाइम का उपयोग करते हैं जिसमें सम्मिलित किया गया था, जो अद्वितीय भी है।
जेवियर ला बंका

35

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

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

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

SELECT RANDSTRING(8)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 ;

6
यह स्वीकृत उत्तर, स्पष्ट और इस बिंदु पर होना चाहिए, मेरे लिए ठीक काम किया, धन्यवाद @ धान-मन्न
सैफ

यह सबसे अच्छा उपाय है जो मुझे लगता है। धन्यवाद दोस्त!
Pronoy999

23

यहाँ एक तरीका है, वैध अक्षरों के रूप में अल्फा न्यूमेरिक्स का उपयोग करना:

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;

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


7
इसके बजाय फर्श (रैंड) (36 * 1) का उपयोग करें। अन्यथा कुछ परिणाम 'छोटे' होंगे।
फ्रैगल

2
35 + 1 नहीं 36 + 1 होना चाहिए! नहीं तो आपको कुछ तार 8
चर के

23

रैंडम स्ट्रिंग उत्पन्न करने के लिए यहां एक और तरीका दिया गया है:

SELECT SUBSTRING(MD5(RAND()) FROM 1 FOR 8) AS myrandomstring


16

आप 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;

14

आप इसके साथ एक यादृच्छिक अल्फ़ान्यूमेरिक स्ट्रिंग उत्पन्न कर सकते हैं:

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

आप इसे 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कॉलम के लिए एक मान उत्पन्न करेगा ।

( वर्गफ्लाय डेमो )

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

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

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


गजब का! जैसा मुझे चाहिए था यह बिल्कुल वैसा ही है। मैं केवल यह समझना चाहूंगा कि यह कैसे एक स्ट्रिंग में परिवर्तित हो जाता है। एक पाव क्यों है, क्या करना है, संख्याओं को जोड़ना आदि। किसी भी तरह, धन्यवाद।
अकक्से

@ Akxe conv () का उपयोग किसी संख्या को अल्फ़ान्यूमेरिक स्ट्रिंग में बदलने के लिए किया जा सकता है। pow(36,8)-1की संख्यात्मक प्रस्तुति है ZZZZZZZZ। इसलिए हम 0'36 ^ 8-1 '(से ) के बीच एक रैंडम पूर्णांक 0बनाते हैं 2821109907455और इसे अल्फान्यूमेरिक स्ट्रिंग के बीच 0और ZZZZZZZZएकजुट करने के लिए परिवर्तित करते हैं conv()लैपड () स्ट्रिंग को जीरो से भरेगा जब तक कि इसकी लंबाई 8 नहीं है।
पॉल स्पीगेल

आप सर एक जीनियस हैं। मैं कल्पना करता हूं कि वर्णों की निरंतरता न होने के कारण छोटे अक्षर जोड़ना असंभव है? (91-96) ऐसा नहीं है कि मुझे इसकी आवश्यकता है, बस जिज्ञासु ...
1

@Axx conv()केवल 36 (10 अंक + 26 अपरकेस अक्षर) तक के आधार का समर्थन करता है। यदि आप लोअरकेस अक्षर शामिल करना चाहते हैं, तो आपको एक संख्या को स्ट्रिंग में बदलने के लिए एक और तरीके की आवश्यकता होगी।
पॉल स्पीगेल

Caveat: str_len के लिए काम नहीं करता है। 13. 14 से, आपको हमेशा '3W5E11264SGSF' मिलता है। ;-)
जेरार्ड एच। पाइल

6

यादृच्छिक स्ट्रिंग उत्पन्न करने के लिए, आप इसका उपयोग कर सकते हैं:

SUBSTRING(MD5(RAND()) FROM 1 FOR 8)

आप इस तरह smth को पुनः प्राप्त करते हैं:

353E50CC


5

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

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

अंदर से बाहर समझाया:

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

महान, वास्तव में मैं MySQL में मूल रूप से एक टोकन जैसी आईडी बनाने के लिए क्या देख रहा था
rabudde

4

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

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

4

वर्णमाला के 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))));

3

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

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

2

अपरकेस और लोअरकेस अक्षरों और अंकों के साथ एक यादृच्छिक 10 वर्ण स्ट्रिंग प्राप्त करने के लिए सरल और कुशल समाधान:

select substring(base64_encode(md5(rand())) from 1+rand()*4 for 10);

1

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


1

आपके द्वारा आवश्यक वर्णों की कुल संख्या को ध्यान में रखते हुए, आपके पास दो समान संख्या प्लेटों को उत्पन्न करने की बहुत कम संभावना होगी। इस प्रकार आप शायद LUA में संख्याओं को उत्पन्न करने से दूर हो सकते हैं।

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

बेशक, यह सब इस बात पर निर्भर करता है कि आप कितने नंबरप्लेट बनाएंगे।


सही है, मैं इसे SQL के बजाय वास्तविक गेम में करता रहूंगा। आपका बहुत बहुत धन्यवाद।
फनस्टीन

1

यह फ़ंक्शन आपकी इनपुट लंबाई और अनुमत वर्णों के आधार पर एक यादृच्छिक स्ट्रिंग उत्पन्न करता है:

SELECT str_rand(8, '23456789abcdefghijkmnpqrstuvwxyz');

फ़ंक्शन कोड:

DROP FUNCTION IF EXISTS str_rand;

DELIMITER //

CREATE FUNCTION str_rand(
    u_count INT UNSIGNED,
    v_chars TEXT
)
RETURNS TEXT
NOT DETERMINISTIC
NO SQL
SQL SECURITY INVOKER
COMMENT ''
BEGIN
    DECLARE v_retval TEXT DEFAULT '';
    DECLARE u_pos    INT UNSIGNED;
    DECLARE u        INT UNSIGNED;

    SET u = LENGTH(v_chars);
    WHILE u_count > 0
    DO
      SET u_pos = 1 + FLOOR(RAND() * u);
      SET v_retval = CONCAT(v_retval, MID(v_chars, u_pos, 1));
      SET u_count = u_count - 1;
    END WHILE;

    RETURN v_retval;
END;
//
DELIMITER ;

यह कोड "रॉस स्मिथ II" द्वारा किए गए फेरबदल स्ट्रिंग फ़ंक्शन पर आधारित है।


यह फ़ंक्शन यादृच्छिक अनन्य मान उत्पन्न नहीं करेगा।
फैसल

1

यादृच्छिक 10 अंक अल्फ़ान्यूमेरिक बनाने के लिए , लुकलाइक चार्ट को छोड़कर 01oOlI:

LPAD(LEFT(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(TO_BASE64(UNHEX(MD5(RAND()))), "/", ""), "+", ""), "=", ""), "O", ""), "l", ""), "I", ""), "1", ""), "0", ""), "o", ""), 10), 10, 0)

यह वही है जो मुझे वाउचर कोड बनाने के लिए आवश्यक था । वाउचर कोड फॉर्म में टाइप करने पर त्रुटियों को कम करने के लिए भ्रमित करने वाले वर्ण हटा दिए जाते हैं।

जान उहलिग के शानदार जवाब के आधार पर होप्स किसी की मदद करता है ।

यह कोड कैसे काम करता है, इस पर ब्रेक के लिए कृपया जन का जवाब देखें।


0
DELIMITER $$

USE `temp` $$

DROP PROCEDURE IF EXISTS `GenerateUniqueValue`$$

CREATE PROCEDURE `GenerateUniqueValue`(IN tableName VARCHAR(255),IN columnName VARCHAR(255)) 
BEGIN
    DECLARE uniqueValue VARCHAR(8) DEFAULT "";
    WHILE LENGTH(uniqueValue) = 0 DO
        SELECT CONCAT(SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1)
                ) INTO @newUniqueValue;
        SET @rcount = -1;
        SET @query=CONCAT('SELECT COUNT(*) INTO @rcount FROM  ',tableName,' WHERE ',columnName,'  like ''',@newUniqueValue,'''');
        PREPARE stmt FROM  @query;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
    IF @rcount = 0 THEN
            SET uniqueValue = @newUniqueValue ;
        END IF ;
    END WHILE ;
    SELECT uniqueValue;
    END$$

DELIMITER ;

इस संग्रहीत प्रक्रिया का उपयोग करें और इसे हर बार की तरह उपयोग करें

Call GenerateUniqueValue('tableName','columnName')

0

एक आसान तरीका जो एक अद्वितीय संख्या उत्पन्न करता है

set @i = 0;
update vehicles set plate = CONCAT(@i:=@i+1, ROUND(RAND() * 1000)) 
order by rand();


0

मैं कुछ इसी तरह की तलाश में था और मैंने अपना खुद का संस्करण बनाने का फैसला किया, जहां आप एक अलग बीज निर्दिष्ट कर सकते हैं यदि पैरामीटर के रूप में वांछित (वर्णों की सूची):

CREATE FUNCTION `random_string`(length SMALLINT(3), seed VARCHAR(255)) RETURNS varchar(255) CHARSET utf8
    NO SQL
BEGIN
    SET @output = '';

    IF seed IS NULL OR seed = '' THEN SET seed = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; END IF;

    SET @rnd_multiplier = LENGTH(seed);

    WHILE LENGTH(@output) < length DO
        # Select random character and add to output
        SET @output = CONCAT(@output, SUBSTRING(seed, RAND() * (@rnd_multiplier + 1), 1));
    END WHILE;

    RETURN @output;
END

के रूप में इस्तेमाल किया जा सकता है:

SELECT random_string(10, '')

जो ऊपरी और निचले अक्षरों + अंकों के अंतर्निहित बीज का उपयोग करेगा। '' के बजाय NULL का भी मूल्य होगा।

लेकिन कोई कस्टम बीज को कॉल करते समय निर्दिष्ट कर सकता है:

SELECT random_string(10, '1234')
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.