एक यादृच्छिक अल्फा-न्यूमेरिक स्ट्रिंग कैसे उत्पन्न करें?


1741

मैं एक छद्म-यादृच्छिक अल्फा-न्यूमेरिक स्ट्रिंग उत्पन्न करने के लिए एक सरल जावा एल्गोरिथ्म की तलाश कर रहा हूं । मेरी स्थिति में इसे एक अनूठे सत्र / प्रमुख पहचानकर्ता के रूप में उपयोग किया जाएगा, जो 500K+पीढ़ी के हिसाब से "संभावित" होगा (मेरी आवश्यकताओं को वास्तव में बहुत अधिक परिष्कृत कुछ भी करने की आवश्यकता नहीं है)।

आदर्श रूप में, मैं अपनी विशिष्टता की जरूरतों के आधार पर एक लंबाई निर्दिष्ट कर सकूंगा। उदाहरण के लिए, लंबाई 12 की एक उत्पन्न स्ट्रिंग कुछ इस तरह दिख सकती है "AEYGF7K0DM1X"



58
यहां तक ​​कि जन्मदिन के विरोधाभास को ध्यान में रखते हुए, यदि आप 12 अल्फ़ान्यूमेरिक वर्ण (62 कुल) का उपयोग करते हैं, तो भी आपको विरोधाभास तक पहुंचने के लिए 34 बिलियन से अधिक स्ट्रिंग्स की आवश्यकता होगी। और जन्मदिन विरोधाभास किसी भी तरह से टक्कर की गारंटी नहीं देता है, यह सिर्फ 50% से अधिक मौका है।
NullUserException

4
@NullUserException 50% सफलता का मौका (प्रति प्रयास) बहुत अधिक है: 10 प्रयासों के साथ भी, सफलता दर 0.999 है। इसके साथ और इस तथ्य के साथ कि आप 24 घंटों की अवधि में ए लॉट की कोशिश कर सकते हैं, आपको कम से कम एक अनुमान लगाने के लिए 34 बिलियन स्ट्रिंग्स की आवश्यकता नहीं है। यही कारण है कि कुछ सत्र टोकन वास्तव में, वास्तव में लंबे होने चाहिए।
पीजूस

16
ये 3 सिंगल लाइन कोड मेरे लिए बहुत उपयोगी हैं ..Long.toHexString(Double.doubleToLongBits(Math.random())); UUID.randomUUID().toString(); RandomStringUtils.randomAlphanumeric(12);
मनिंदर

18
@Pijusn मैं जानता हूँ कि यह पुराना है, लेकिन ... "50% संभावना" जन्मदिन विरोधाभास में है नहीं "कोशिश प्रति", यह "है 50% संभावना है कि, से बाहर 34 बिलियन तार (इस मामले में), वहाँ पर मौजूद है कम से कम एक जोड़ी नकलची ”। आप 1.6 आवश्यकता होगी सितम्बर क्रम में अपने डेटाबेस में प्रविष्टियों वहाँ कोशिश प्रति 50% संभावना होने के लिए - 1.6e21 - illion।
टिन जादूगर

जवाबों:


1541

कलन विधि

एक यादृच्छिक स्ट्रिंग उत्पन्न करने के लिए, संक्षिप्त वर्णों को स्वीकार्य प्रतीकों के सेट से यादृच्छिक रूप से खींचा जाता है जब तक कि स्ट्रिंग वांछित लंबाई तक नहीं पहुंच जाती।

कार्यान्वयन

यादृच्छिक पहचानकर्ता उत्पन्न करने के लिए यहां कुछ सरल और बहुत ही लचीला कोड है। महत्वपूर्ण एप्लिकेशन नोटों के लिए निम्नलिखित जानकारी पढ़ें

public class RandomString {

    /**
     * Generate a random string.
     */
    public String nextString() {
        for (int idx = 0; idx < buf.length; ++idx)
            buf[idx] = symbols[random.nextInt(symbols.length)];
        return new String(buf);
    }

    public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    public static final String lower = upper.toLowerCase(Locale.ROOT);

    public static final String digits = "0123456789";

    public static final String alphanum = upper + lower + digits;

    private final Random random;

    private final char[] symbols;

    private final char[] buf;

    public RandomString(int length, Random random, String symbols) {
        if (length < 1) throw new IllegalArgumentException();
        if (symbols.length() < 2) throw new IllegalArgumentException();
        this.random = Objects.requireNonNull(random);
        this.symbols = symbols.toCharArray();
        this.buf = new char[length];
    }

    /**
     * Create an alphanumeric string generator.
     */
    public RandomString(int length, Random random) {
        this(length, random, alphanum);
    }

    /**
     * Create an alphanumeric strings from a secure generator.
     */
    public RandomString(int length) {
        this(length, new SecureRandom());
    }

    /**
     * Create session identifiers.
     */
    public RandomString() {
        this(21);
    }

}

उपयोग के उदाहरण

8-वर्ण पहचानकर्ताओं के लिए एक असुरक्षित जनरेटर बनाएँ:

RandomString gen = new RandomString(8, ThreadLocalRandom.current());

सत्र पहचानकर्ताओं के लिए एक सुरक्षित जनरेटर बनाएँ:

RandomString session = new RandomString();

मुद्रण के लिए आसान-से-पढ़ने वाले कोड के साथ एक जनरेटर बनाएं। कम प्रतीकों का उपयोग करने के लिए क्षतिपूर्ति के लिए तार पूर्ण अल्फ़ान्यूमेरिक स्ट्रिंग्स की तुलना में अधिक हैं:

String easy = RandomString.digits + "ACEFGHJKLMNPQRUVWXYabcdefhijkprstuvwx";
RandomString tickets = new RandomString(23, new SecureRandom(), easy);

सत्र पहचानकर्ता के रूप में उपयोग करें

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

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

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

ऑब्जेक्ट पहचानकर्ता के रूप में उपयोग करें

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

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

पहचानकर्ताओं का उपयोग करने के लिए भी ध्यान रखा जाना चाहिए, जो कि लंबे समय तक टकराव करने के लिए पर्याप्त हैं, जो कि पहचानकर्ताओं की अनुमानित कुल संख्या को देखते हुए संभव नहीं है। इसे "जन्मदिन विरोधाभास" कहा जाता है। टकराव, पी की संभावना लगभग n 2 / (2q x ) है, जहां n वास्तव में उत्पन्न पहचानकर्ताओं की संख्या है, q वर्णमाला में अलग-अलग प्रतीकों की संख्या है, और x पहचानकर्ताओं की लंबाई है। यह बहुत छोटी संख्या होनी चाहिए, जैसे 2 a50 या उससे कम।

इस पर काम करने से पता चलता है कि 500k 15-वर्ण पहचानकर्ताओं के बीच टकराव की संभावना लगभग 2 , 52 है , जो कि ब्रह्मांडीय किरणों से अनिर्धारित त्रुटियों की संभावना कम है, आदि।

यूयूआईडी के साथ तुलना

उनके विनिर्देश के अनुसार, यूयूआईडी को अप्रत्याशित नहीं बनाया गया है, और इसका उपयोग सत्र पहचानकर्ताओं के रूप में नहीं किया जाना चाहिए

UUIDs अपने मानक प्रारूप में बहुत अधिक स्थान लेते हैं: केवल 122 बिट्स एन्ट्रापी के लिए 36 वर्ण। ("यादृच्छिक" UUID के सभी बिट्स को यादृच्छिक रूप से नहीं चुना जाता है।) एक बेतरतीब ढंग से चुने गए अल्फ़ान्यूमेरिक स्ट्रिंग पैक केवल 21 वर्णों में अधिक एन्ट्रॉपी हैं।

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


6
यदि आपको आप में रिक्त स्थान की आवश्यकता है, तो आप रेगेक्स स्वैप करने .replaceAll("\\d", " ");के लिए return new BigInteger(130, random).toString(32);लाइन के अंत में निपट सकते हैं। यह रिक्त स्थान के साथ सभी अंकों को बदलता है। मेरे लिए बहुत अच्छा काम करता है: मैं इसे फ्रंट-एंड
लोरम इप्सम के

4
@weisjohn यह एक अच्छा विचार है। आप दूसरी विधि के साथ कुछ ऐसा कर सकते हैं, जिससे अंकों को हटाकर symbolsइसके स्थान का उपयोग किया जा सकता है; आप प्रतीकों में रिक्त स्थान की संख्या (छोटे शब्दों के लिए अधिक घटनाएं) को बदलकर औसत "शब्द" की लंबाई को नियंत्रित कर सकते हैं। वास्तव में ओवर-द-टॉप नकली पाठ समाधान के लिए, आप एक मार्कोव श्रृंखला का उपयोग कर सकते हैं!
इरिकसन

4
ये पहचानकर्ता बेतरतीब ढंग से एक निश्चित आकार के स्थान से चुने जाते हैं। वे 1 वर्ण लंबे हो सकते हैं। यदि आप एक निश्चित लंबाई चाहते हैं, तो आप दूसरे समाधान का उपयोग कर सकते हैं, SecureRandomउदाहरण के लिए randomचर को सौंपा गया ।
इरिकसन

15
.ToString (32) के बजाय .toString (36) क्यों?
ejain

17
@ ईजेन क्योंकि 32 = 2 ^ 5; प्रत्येक वर्ण ठीक 5 बिट्स का प्रतिनिधित्व करेगा, और 130 बिट्स को समान रूप से वर्णों में विभाजित किया जा सकता है।
इरिकसन

817

जावा सीधे ऐसा करने का एक तरीका है। यदि आप डैश नहीं चाहते हैं, तो वे अलग करना आसान है। महज प्रयोग करेंuuid.replace("-", "")

import java.util.UUID;

public class randomStringGenerator {
    public static void main(String[] args) {
        System.out.println(generateString());
    }

    public static String generateString() {
        String uuid = UUID.randomUUID().toString();
        return "uuid = " + uuid;
    }
}

आउटपुट:

uuid = 2d7428a6-b58c-4008-8575-f05549f16316

33
खबरदार कि यह समाधान केवल हेक्साडेसिमल वर्णों के साथ एक यादृच्छिक स्ट्रिंग उत्पन्न करता है। जो कुछ मामलों में ठीक हो सकता है।
डेव

5
यूयूआईडी वर्ग उपयोगी है। हालाँकि, वे मेरे उत्तरों द्वारा निर्मित पहचानकर्ताओं के रूप में कॉम्पैक्ट नहीं हैं। यह एक मुद्दा हो सकता है, उदाहरण के लिए, URL में। अपनी आवश्यकताओं पर निर्भर करता है।
इरिकसन

6
@Ruggs - लक्ष्य अल्फा-न्यूमेरिक स्ट्रिंग्स है। किसी भी संभावित बाइट्स के लिए आउटपुट को व्यापक बनाने के साथ कैसे फिट होता है?
erickson

72
UFC के टोकन के रूप में RFC4122 का उपयोग करना एक बुरा विचार है: यह मत मानो कि UUID का अनुमान लगाना कठिन है; उदाहरण के लिए, उन्हें सुरक्षा क्षमताओं के रूप में उपयोग नहीं किया जाना चाहिए (पहचानकर्ता जिनके पास केवल पहुंच अनुदान है)। एक पूर्वानुमानित यादृच्छिक संख्या स्रोत स्थिति को बढ़ा देगा। ietf.org/rfc/rfc4122.txt
सोमाटिक

34
UUID.randomUUID().toString().replaceAll("-", "");अनुरोध के रूप में स्ट्रिंग अल्फा-न्यूमेरिक बनाता है।
न्यूमिड

546
static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static SecureRandom rnd = new SecureRandom();

String randomString( int len ){
   StringBuilder sb = new StringBuilder( len );
   for( int i = 0; i < len; i++ ) 
      sb.append( AB.charAt( rnd.nextInt(AB.length()) ) );
   return sb.toString();
}

61
+1, निर्दिष्ट लंबाई का एक यादृच्छिक स्ट्रिंग उत्पन्न करने के लिए यहां सबसे सरल समाधान (कॉमन्स लैंग से रैंडमस्ट्रिंग यूटिल्स का उपयोग करने के अलावा)।
जोनीक

12
कक्षा के SecureRandomबजाय उपयोग करने पर विचार करें Random। यदि पासवर्ड किसी सर्वर पर उत्पन्न होते हैं, तो यह समय के हमलों के लिए असुरक्षित हो सकता है।
foens

8
मैं लोअरकेस को भी जोड़ूंगा: AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";और कुछ अन्य स्वीकृत वर्णों को।
एसीवी

1
static Random rnd = new Random();पद्धति के अंदर क्यों नहीं रखा गया?
माइक्रो

4
@MicroR Randomप्रत्येक विधि मंगलाचरण में वस्तु बनाने का एक अच्छा कारण है ? मुझे ऐसा नहीं लगता।
कैसियोमोलिन

484

यदि आप अपाचे कक्षाओं का उपयोग करके खुश हैं, तो आप org.apache.commons.text.RandomStringGenerator(कॉमन्स-टेक्स्ट) का उपयोग कर सकते हैं ।

उदाहरण:

RandomStringGenerator randomStringGenerator =
        new RandomStringGenerator.Builder()
                .withinRange('0', 'z')
                .filteredBy(CharacterPredicates.LETTERS, CharacterPredicates.DIGITS)
                .build();
randomStringGenerator.generate(12); // toUpperCase() if you want

चूंकि कॉमन्स-लैंग 3.6, RandomStringUtilsपदावनत है।


22
सिर्फ लाइब्रेरी के उल्लेखित वर्ग के माध्यम से देखा गया है Apache Commons Lang 3.3.1- और यह केवल java.util.Randomयादृच्छिक क्रम प्रदान करने के लिए उपयोग कर रहा है , इसलिए यह असुरक्षित दृश्यों का उत्पादन कर रहा है ।
यूरी नकोनचाय

16
रैंडमस्ट्रिंग यूटिल्स का उपयोग करते समय सुनिश्चित करें कि आप SecureRandom का उपयोग करते हैं:public static java.lang.String random(int count, int start, int end, boolean letters, boolean numbers, @Nullable char[] chars, java.util.Random random)
Ruslans Uralovs

प्रयोग नहीं करें। यह असुरक्षित क्रम बनाता है !
पैट्रिक फेवर

109

आप इसके लिए अपाचे लाइब्रेरी का उपयोग कर सकते हैं: रैंडमस्ट्रिंग यूटिल्स

RandomStringUtils.randomAlphanumeric(20).toUpperCase();

18
@kamil, मैंने RandomStringUtils के स्रोत कोड को देखा, और यह java.util के एक उदाहरण का उपयोग करता है। आरेख बिना तर्क के त्वरित। Java.util.Random के लिए प्रलेखन यह कहता है कि यदि कोई बीज उपलब्ध नहीं कराया गया है तो यह वर्तमान प्रणाली समय का उपयोग करता है। इसका मतलब यह है कि इसका उपयोग सत्र पहचानकर्ताओं / चाबियों के लिए नहीं किया जा सकता है क्योंकि एक हमलावर आसानी से यह अनुमान लगा सकता है कि किसी भी समय उत्पन्न सत्र पहचानकर्ता क्या हैं।
इंशाल्लाह

36
@Inshallah: आप (अनावश्यक रूप से) सिस्टम को चुनौती दे रहे हैं। जबकि मैं मानता हूं कि यह बीज के रूप में समय का उपयोग करता है, हमलावर को वास्तव में वह प्राप्त करने के लिए निम्नलिखित डेटा तक पहुंच प्राप्त करना होता है। 1. सटीक मिलीसेकंड के लिए समय, जब कोड बोया गया था 2. अब तक हुई कॉलों की संख्या 3. अपने खुद के कॉल के लिए एटमॉसिस (ताकि कॉल की संख्या-अब तक के रेमन्स समान) यदि आपके हमलावर में इन तीनों चीजें हैं, तो आपके पास हाथ में बहुत बड़ा मुद्दा है ...
अजीत गंगा

3
gradle निर्भरता: compile 'commons-lang:commons-lang:2.6'
younes0

4
@ सच यह सच नहीं है। आप इसके आउटपुट से यादृच्छिक संख्या जनरेटर की स्थिति प्राप्त कर सकते हैं। यदि कोई हमलावर यादृच्छिक एपीआई टोकन उत्पन्न करने के लिए कुछ हज़ार कॉल उत्पन्न कर सकता है तो हमलावर भविष्य के सभी एपीआई टोकन की भविष्यवाणी करने में सक्षम होगा।
थॉमस ग्रेंजर

3
@AjeetGanga इंजीनियरिंग से अधिक कुछ नहीं करना है। यदि आप सत्र आईडी बनाना चाहते हैं, तो आपको एक क्रिप्टोग्राफिक छद्म यादृच्छिक जनरेटर की आवश्यकता है। बीज के रूप में समय का उपयोग करने वाले प्रत्येक चुभन पूर्वानुमान योग्य है और डेटा के लिए बहुत असुरक्षित है जो अप्रत्याशित होना चाहिए। बस उपयोग करें SecureRandomऔर आप अच्छे हैं।
पैट्रिक

105

एक पंक्ति में:

Long.toHexString(Double.doubleToLongBits(Math.random()));

http://mynotes.wordpress.com/2009/07/23/java-generating-random-string/


9
लेकिन केवल 6 अक्षर :(
मोशे रेवह

2
इससे मुझे भी मदद मिली, लेकिन केवल हेक्साडेसिमल अंक :(
noquery

@Zippoxer, आप इसे कई बार
समेट सकते हैं

7
ओपी के उदाहरण ने निम्नलिखित स्ट्रिंग को एक उदाहरण के रूप में दिखाया AEYGF7K0DM1Xजो कि हेक्साडेसिमल नहीं है। यह मुझे चिंतित करता है कि लोग हेक्साडेसिमल के साथ अल्फ़ान्यूमेरिक को कितनी बार गलती करते हैं। ये एक ही चीज नहीं हैं।
hfontanez

6
यह बहुत कम यादृच्छिक है की तुलना में यह स्ट्रिंग लंबाई दी जानी चाहिए के रूप में Math.random()एक पैदा करता है double, 0 और 1 के बीच इतना प्रतिपादक हिस्सा ज्यादातर अप्रयुक्त है। इस बदसूरत हैक के बजाय random.nextLongएक यादृच्छिक के लिए उपयोग करें long
माआर्टिनस

80

यह किसी भी बाहरी पुस्तकालयों के बिना आसानी से प्राप्त करने योग्य है।

1. क्रिप्टोग्राफिक छद्म यादृच्छिक डेटा पीढ़ी

सबसे पहले आपको एक क्रिप्टोग्राफिक PRNG की आवश्यकता है। जावा के SecureRandomलिए है और आम तौर पर मशीन (जैसे /dev/random) पर सबसे अच्छा एन्ट्रोपी स्रोत का उपयोग करता है । यहाँ और पढ़ें

SecureRandom rnd = new SecureRandom();
byte[] token = new byte[byteLength];
rnd.nextBytes(token);

नोट: SecureRandom यादृच्छिक बाइट्स बनाने के जावा में सबसे धीमा, लेकिन सबसे सुरक्षित तरीका है। मैं हालांकि यहाँ प्रदर्शन पर विचार नहीं करने की सलाह देता हूँ क्योंकि यह आमतौर पर आपके आवेदन पर कोई वास्तविक प्रभाव नहीं डालता है जब तक कि आपको प्रति सेकंड लाखों टोकन उत्पन्न न करने हों।

2. संभावित मूल्यों का आवश्यक स्थान

इसके बाद आपको यह तय करना होगा कि आपका टोकन कितना विशिष्ट है। एन्ट्रॉपी पर विचार करने का पूरा और एकमात्र बिंदु यह सुनिश्चित करना है कि सिस्टम ब्रूट बल के हमलों का विरोध कर सकता है: संभावित मूल्यों का स्थान इतना बड़ा होना चाहिए कि कोई भी हमलावर नॉन-ल्यूडीसिक समय 1 में मानों के एक नगण्य अनुपात की कोशिश कर सके । यादृच्छिक जैसे अद्वितीय पहचानकर्ताओं में UUID122 बिट ऑफ एन्ट्रॉपी (जैसे। 2 ^ 122 = 5.3x10 ^ 36) - टक्कर का मौका "* (...) है, जो नकल के एक अरब मौके में एक होने के लिए है, 103 ट्रिलियन संस्करण 4 यूयूआईडी 2 " उत्पन्न होने चाहिए । हम 128 बिट का चयन करेंगे क्योंकि यह 16 बाइट्स में बिल्कुल फिट बैठता है और इसे अत्यधिक पर्याप्त के रूप में देखा जाता हैमूल रूप से हर के लिए अद्वितीय होने के लिए, लेकिन सबसे चरम, मामलों का उपयोग करें और आपको डुप्लिकेट के बारे में सोचने की ज़रूरत नहीं है। यहां एन्ट्रॉपी की एक सरल तुलना तालिका है जिसमें जन्मदिन की समस्या का सरल विश्लेषण शामिल है

टोकन साइज की तुलना

साधारण आवश्यकताओं के लिए 8 या 12 बाइट की लंबाई पर्याप्त हो सकती है, लेकिन 16 बाइट्स के साथ आप "सुरक्षित पक्ष" पर हैं।

और वह मूल रूप से यह है। अंतिम बात एन्कोडिंग के बारे में सोचना है ताकि इसे प्रिंट करने योग्य पाठ (पढ़ें, क String) के रूप में दर्शाया जा सके ।

3. बाइनरी टू टेक्स्ट एनकोडिंग

विशिष्ट एन्कोडिंग में शामिल हैं:

  • Base64हर चरित्र एक 33% उपरि बनाने 6bit सांकेतिक शब्दों में बदलना। सौभाग्य से जावा 8+ और एंड्रॉइड में मानक कार्यान्वयन हैं । पुराने जावा के साथ आप कई थर्ड पार्टी लाइब्रेरी का इस्तेमाल कर सकते हैं । यदि आप चाहते हैं कि आपके टोकन सुरक्षित रहें तो RFC4648 के url- सुरक्षित संस्करण का उपयोग करें (जो आमतौर पर अधिकांश कार्यान्वयन द्वारा समर्थित है)। उदाहरण के लिए 16 बाइट्स पैडिंग के साथ एन्कोडिंग:XfJhfv3C0P6ag7y9VQxSbw==

  • Base32हर चरित्र 5bit को 40% ओवरहेड बनाता है। इस का उपयोग करेगा A-Zऔर 2-7वह उचित रूप से अंतरिक्ष कुशल, जबकि केस-संवेदी अल्फा-न्यूमेरिक जा रहा है बना रही है। JDK में कोई मानक कार्यान्वयन नहीं है । उदाहरण ब्रेडिंग के बिना 16 बाइट्स एन्कोडिंग:WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16(हेक्स) प्रत्येक वर्ण 4 बाइट्स को बाइट में 2 वर्णों की आवश्यकता करता है (यानी 16 बाइट लंबाई 32 की एक स्ट्रिंग बनाते हैं)। इसलिए हेक्स की तुलना में कम जगह कुशल है Base32लेकिन ज्यादातर मामलों में उपयोग करने के लिए सुरक्षित है (यूआरएल) क्योंकि यह केवल उपयोग करता है 0-9और Aकरने के लिए F। उदाहरण 16 बाइट्स एन्कोडिंग 4fa3dd0f57cb3bf331441ed285b27735:। यहाँ हेक्स में परिवर्तित करने के बारे में एक SO चर्चा देखें।

Base85 और विदेशी Base122 जैसी अतिरिक्त एन्कोडिंग बेहतर / बदतर अंतरिक्ष दक्षता के साथ मौजूद हैं। आप अपनी स्वयं की एन्कोडिंग बना सकते हैं (जो मूल रूप से इस थ्रेड में अधिकांश उत्तर देते हैं) लेकिन मैं इसके खिलाफ सलाह दूंगा, यदि आपके पास बहुत विशिष्ट आवश्यकताएं नहीं हैं। विकिपीडिया लेख में अधिक एन्कोडिंग योजनाएँ देखें

4. सारांश और उदाहरण

  • उपयोग SecureRandom
  • संभव मानों के कम से कम 16 बाइट्स (2 ^ 128) का उपयोग करें
  • अपनी आवश्यकताओं के अनुसार सांकेतिक शब्दों में बदलना (आमतौर पर hexया base32यदि आपको अल्फा-न्यूमेरिक होने की आवश्यकता है)

नहीं

  • ... अपने घर काढ़ा एन्कोडिंग का उपयोग करें: दूसरों के लिए बेहतर बनाए रखने योग्य और पठनीय यदि वे देखते हैं कि एक समय में चार्ट बनाने वाले छोरों के लिए अजीब के बजाय आप किस मानक एन्कोडिंग का उपयोग करते हैं।
  • ... UUID का उपयोग करें: यह यादृच्छिकता पर कोई गारंटी नहीं है; आप एन्ट्रापी के 6 बिट्स को बर्बाद कर रहे हैं और क्रिया स्ट्रिंग प्रतिनिधित्व है

उदाहरण: हेक्स टोकन जेनरेटर

public static String generateRandomHexToken(int byteLength) {
    SecureRandom secureRandom = new SecureRandom();
    byte[] token = new byte[byteLength];
    secureRandom.nextBytes(token);
    return new BigInteger(1, token).toString(16); //hex encoding
}

//generateRandomHexToken(16) -> 2189df7475e96aa3982dbeab266497cd

उदाहरण: बेस 64 टोकन जेनरेटर (यूआरएल सेफ)

public static String generateRandomBase64Token(int byteLength) {
    SecureRandom secureRandom = new SecureRandom();
    byte[] token = new byte[byteLength];
    secureRandom.nextBytes(token);
    return Base64.getUrlEncoder().withoutPadding().encodeToString(token); //base64 encoding
}

//generateRandomBase64Token(16) -> EEcCCAYuUcQk7IuzdaPzrg

उदाहरण: जावा सीएलआई उपकरण

यदि आप एक रेडी-टू-यूज़ क्ली टूल चाहते हैं तो आप पासा का उपयोग कर सकते हैं: https://github.com/patrickfav/dice

उदाहरण: संबंधित मुद्दा - अपने वर्तमान Ids की सुरक्षा करें

यदि आपके पास पहले से ही एक आईडी है, जिसका आप उपयोग कर सकते हैं (जैसे longआपकी इकाई में एक सिंथेटिक ), लेकिन आंतरिक मूल्य प्रकाशित नहीं करना चाहते हैं , तो आप इस लाइब्रेरी का उपयोग इसे एन्क्रिप्ट करने और इसे बाधित करने के लिए कर सकते हैं: https://github.com/patrickfav / आईडी-मुखौटा

IdMask<Long> idMask = IdMasks.forLongIds(Config.builder(key).build());
String maskedId = idMask.mask(id);
//example: NPSBolhMyabUBdTyanrbqT8
long originalId = idMask.unmask(maskedId);

3
यह उत्तर पूर्ण है और किसी भी निर्भरता को जोड़े बिना काम करता है। यदि आप आउटपुट में संभावित माइनस संकेतों से बचना चाहते हैं, तो आप BigIntegerएक कंस्ट्रक्टर पैरामीटर का उपयोग करके नकारात्मक एस को रोक सकते हैं : के BigInteger(1, token)बजाय BigInteger(token)
फ्रैंकोइज़र

संकेत के लिए टैंक्स @francoisr, मैंने कोड उदाहरण को संपादित किया
पैट्रिक फेव्रे

import java.security.SecureRandom;और import java.math.BigInteger;उदाहरण के काम करने के लिए आवश्यक हैं, लेकिन यह महान काम करता है!
anothermh

अच्छा उत्तर लेकिन / देव / यादृच्छिक एक अवरोधन विधि है, यही कारण है कि यदि एन्ट्रापी बहुत कम है, तो यह अवरोध के बिंदु तक धीमा है। बेहतर और गैर-अवरोधक विधि है / देव / उर्गम। इस <JRE> /lib/security/java.security और सेट securerandom.source = फ़ाइल के माध्यम से विन्यस्त किया जा सकता: / dev /./ urandom
मुजम्मिल

@ मुज़म्मिल tersesystems.com/blog/2015/12/17/… (उत्तर में भी जुड़ा हुआ है) देखें - new SecureRandom()उपयोग/dev/urandom
पैट्रिक

42

डॉलर का उपयोग सरल होना चाहिए:

// "0123456789" + "ABCDE...Z"
String validCharacters = $('0', '9').join() + $('A', 'Z').join();

String randomString(int length) {
    return $(validCharacters).shuffle().slice(length).toString();
}

@Test
public void buildFiveRandomStrings() {
    for (int i : $(5)) {
        System.out.println(randomString(12));
    }
}

यह कुछ इस तरह का उत्पादन करता है:

DKL1SBH9UJWC
JH7P0IT21EA5
5DTI72EO6SFU
HQUMJTEBNF7Y
1HCR6SKYWGT7

क्या फेरबदल के साथ SecureRandom का उपयोग करना संभव है?
इविन

34

यहाँ यह जावा में है:

import static java.lang.Math.round;
import static java.lang.Math.random;
import static java.lang.Math.pow;
import static java.lang.Math.abs;
import static java.lang.Math.min;
import static org.apache.commons.lang.StringUtils.leftPad

public class RandomAlphaNum {
  public static String gen(int length) {
    StringBuffer sb = new StringBuffer();
    for (int i = length; i > 0; i -= 12) {
      int n = min(12, abs(i));
      sb.append(leftPad(Long.toString(round(random() * pow(36, n)), 36), n, '0'));
    }
    return sb.toString();
  }
}

यहाँ एक नमूना रन है:

scala> RandomAlphaNum.gen(42)
res3: java.lang.String = uja6snx21bswf9t89s00bxssu8g6qlu16ffzqaxxoy

4
यह असुरक्षित सीक्वेंस यानी सीक्वेंस का निर्माण करेगा जिसका आसानी से अनुमान लगाया जा सकता है।
यूरी नकोनचाय

8
यह सब डबल-इंफ़ेक्ट रैंडम इंट जनरेशन डिज़ाइन, स्लो और अनरीड से टूट गया है। का प्रयोग करें Random#nextIntया nextLongSecureRandomजरूरत पड़ने पर स्विच करें ।
मआर्टिनस जूल

31

आश्चर्यजनक रूप से यहाँ किसी ने भी इसका सुझाव नहीं दिया है:

import java.util.UUID

UUID.randomUUID().toString();

आसान।

इसका लाभ यूयूआईडी अच्छा और लंबा है और टकराने के लिए लगभग असंभव होने की गारंटी है।

विकिपीडिया में इसकी अच्छी व्याख्या है:

"... अगले 100 वर्षों तक हर सेकंड 1 बिलियन यूयूआईडी बनाने के बाद, केवल एक डुप्लिकेट बनाने की संभावना लगभग 50% होगी।"

http://en.wikipedia.org/wiki/Universally_unique_identifier#Random_UUID_probability_of_duplicates

पहले 4 बिट्स संस्करण प्रकार और 2 संस्करण के लिए हैं ताकि आपको 122 बिट्स यादृच्छिक मिलें। तो अगर आप चाहते हैं कि आप यूयूआईडी के आकार को कम करने के लिए अंत से अलग कर सकते हैं। यह अनुशंसित नहीं है लेकिन आपके पास अभी भी यादृच्छिकता का भार है, आपके 500k रिकॉर्ड के लिए पर्याप्त है।


39
आपके सामने लगभग एक साल पहले किसी ने इसका सुझाव दिया था
एरिकसन

31

एक छोटा और आसान उपाय, लेकिन केवल लोअरकेस और न्यूमेरिक्स का उपयोग करता है:

Random r = new java.util.Random ();
String s = Long.toString (r.nextLong () & Long.MAX_VALUE, 36);

आकार 12 अंकों के बेस 36 का है और इसे और बेहतर नहीं बनाया जा सकता है। बेशक आप कई उदाहरण जोड़ सकते हैं।


11
बस ध्यान रखें, कि परिणाम का एक न्यूनतम साइन इनसाइट का 50% मौका है! तो रैपिंग r.nextLong () इन ए मैथ.ब्स () का उपयोग किया जा सकता है, अगर आप माइनस साइन नहीं चाहते हैं: Long.toString(Math.abs(r.nextLong()), 36);
रे हुलहा

5
@RayHulha: यदि आप माइनस साइन नहीं चाहते हैं, तो आपको इसे काट देना चाहिए, क्योंकि आश्चर्यजनक रूप से, Math.abs Long.MIN_VALUE के लिए एक नकारात्मक मान लौटाता है।
यूजर अनजान

दिलचस्प Math.abs नकारात्मक लौट रहा है। यहाँ और अधिक: bmaurer.blogspot.co.nz/2006/10/…
फिल

1
absसबसे महत्वपूर्ण बिट को खाली करने के लिए बिटवाइज़ ऑपरेटर का उपयोग करके समस्या को हल किया जाता है। यह सभी मूल्यों के लिए काम करेगा।
रादोडिफ़

1
@ रोडियोफ यह अनिवार्य रूप से @userunkown ने कहा है। मुझे लगता है आप भी कर सकते थे << 1 >>> 1
shmosel

15

जावा 8 में एक विकल्प है:

static final Random random = new Random(); // Or SecureRandom
static final int startChar = (int) '!';
static final int endChar = (int) '~';

static String randomString(final int maxLength) {
  final int length = random.nextInt(maxLength + 1);
  return random.ints(length, startChar, endChar + 1)
        .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
        .toString();
}

3
यह बहुत अच्छा है - लेकिन अगर आप इसे सख्ती से अल्फ़ान्यूमेरिक (0-9, az, AZ) पर रखना चाहते हैं तो यहां देखें rationaljava.com/2015/06/…
Dan

12

UUIDs का उपयोग करना असुरक्षित है, क्योंकि UUID के कुछ भाग यादृच्छिक नहीं हैं। @Erickson की प्रक्रिया बहुत साफ-सुथरी है, लेकिन यह समान लंबाई के तार नहीं बनाती है। निम्नलिखित स्निपेट पर्याप्त होना चाहिए:

/*
 * The random generator used by this class to create random keys.
 * In a holder class to defer initialization until needed.
 */
private static class RandomHolder {
    static final Random random = new SecureRandom();
    public static String randomKey(int length) {
        return String.format("%"+length+"s", new BigInteger(length*5/*base 32,2^5*/, random)
            .toString(32)).replace('\u0020', '0');
    }
}

क्यों चुना length*5? आइए एक लंबाई के यादृच्छिक स्ट्रिंग के सरल मामले को मानें, इसलिए एक यादृच्छिक चरित्र। यादृच्छिक अंक पाने के लिए सभी अंक 0-9 और अक्षर az वाले होते हैं, हमें प्रत्येक वर्ण में से एक पाने के लिए 0 से 35 के बीच एक यादृच्छिक संख्या की आवश्यकता होगी। BigIntegerएक यादृच्छिक संख्या उत्पन्न करने के लिए एक कंस्ट्रक्टर प्रदान करता है, जो समान रूप से सीमा पर वितरित किया जाता है 0 to (2^numBits - 1)। दुर्भाग्य से 35 कोई संख्या नहीं है जिसे 2 ^ संख्या द्वारा प्राप्त किया जा सकता है - 1. इसलिए हमारे पास दो विकल्प हैं: या तो साथ जाएं 2^5-1=31या 2^6-1=63। यदि हम चुनते हैं 2^6तो हमें "अनावश्यक" / "लंबे" नंबर मिलेंगे। इसलिए 2^5बेहतर विकल्प है, भले ही हम 4 वर्ण (wz) को ढीला कर दें। अब एक निश्चित लंबाई की एक स्ट्रिंग उत्पन्न करने के लिए, हम बस एक का उपयोग कर सकते हैं2^(length*numBits)-1नंबर। आखिरी समस्या, अगर हम एक निश्चित लंबाई के साथ एक स्ट्रिंग चाहते हैं, तो यादृच्छिक एक छोटी संख्या उत्पन्न कर सकता है, इसलिए लंबाई पूरी नहीं होती है, इसलिए हमें स्ट्रिंग को पैड करने की आवश्यकता है जो कि लंबित शून्य के लिए आवश्यक है।


क्या आप बेहतर 5 समझा सकते हैं?
जूलियन सुआरेज़

11
public static String generateSessionKey(int length){
String alphabet = 
        new String("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"); //9
int n = alphabet.length(); //10

String result = new String(); 
Random r = new Random(); //11

for (int i=0; i<length; i++) //12
    result = result + alphabet.charAt(r.nextInt(n)); //13

return result;
}

10
import java.util.Random;

public class passGen{
    //Verison 1.0
    private static final String dCase = "abcdefghijklmnopqrstuvwxyz";
    private static final String uCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String sChar = "!@#$%^&*";
    private static final String intChar = "0123456789";
    private static Random r = new Random();
    private static String pass = "";

    public static void main (String[] args) {
        System.out.println ("Generating pass...");
        while (pass.length () != 16){
            int rPick = r.nextInt(4);
            if (rPick == 0){
                int spot = r.nextInt(25);
                pass += dCase.charAt(spot);
            } else if (rPick == 1) {
                int spot = r.nextInt (25);
                pass += uCase.charAt(spot);
            } else if (rPick == 2) {
                int spot = r.nextInt (7);
                pass += sChar.charAt(spot);
            } else if (rPick == 3){
                int spot = r.nextInt (9);
                pass += intChar.charAt (spot);
            }
        }
        System.out.println ("Generated Pass: " + pass);
    }
}

तो यह क्या करता है बस स्ट्रिंग में पासवर्ड जोड़ें और ... हाँ अच्छा काम करता है इसे बाहर की जाँच करें ... बहुत सरल। मैने यह लिखा


मैंने खुद को कुछ मामूली संशोधन करने की अनुमति दी। आप इसे + 0अक्सर क्यों जोड़ते हैं ? आप स्पॉट और आरंभीकरण की घोषणा को क्यों विभाजित करते हैं? 0,1,2,3 के बजाय अनुक्रमित 1,2,3,4 का क्या फायदा है? सबसे महत्वपूर्ण बात: आपने एक यादृच्छिक मूल्य लिया, और अगर-और के साथ तुलना में 4 बार एक नया मूल्य, जो हमेशा बेमेल हो सकता है, बिना अधिक यादृच्छिकता प्राप्त किए। लेकिन रोलबैक के लिए स्वतंत्र महसूस करें।
उपयोगकर्ता अज्ञात

8

मुझे यह समाधान मिला जो एक यादृच्छिक हेक्स एन्कोडेड स्ट्रिंग उत्पन्न करता है। प्रदान की गई इकाई परीक्षण मेरे प्राथमिक उपयोग के मामले को पकड़ती है। हालांकि, यह प्रदान किए गए कुछ अन्य उत्तरों की तुलना में थोड़ा अधिक जटिल है।

/**
 * Generate a random hex encoded string token of the specified length
 *  
 * @param length
 * @return random hex string
 */
public static synchronized String generateUniqueToken(Integer length){ 
    byte random[] = new byte[length];
    Random randomGenerator = new Random();
    StringBuffer buffer = new StringBuffer();

    randomGenerator.nextBytes(random);

    for (int j = 0; j < random.length; j++) {
        byte b1 = (byte) ((random[j] & 0xf0) >> 4);
        byte b2 = (byte) (random[j] & 0x0f);
        if (b1 < 10)
            buffer.append((char) ('0' + b1));
        else
            buffer.append((char) ('A' + (b1 - 10)));
        if (b2 < 10)
            buffer.append((char) ('0' + b2));
        else
            buffer.append((char) ('A' + (b2 - 10)));
    }
    return (buffer.toString());
}

@Test
public void testGenerateUniqueToken(){
    Set set = new HashSet();
    String token = null;
    int size = 16;

    /* Seems like we should be able to generate 500K tokens 
     * without a duplicate 
     */
    for (int i=0; i<500000; i++){
        token = Utility.generateUniqueToken(size);

        if (token.length() != size * 2){
            fail("Incorrect length");
        } else if (set.contains(token)) {
            fail("Duplicate token generated");
        } else{
            set.add(token);
        }
    }
}

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

8
  1. अपनी आवश्यकताओं के अनुसार स्ट्रिंग वर्ण बदलें।

  2. स्ट्रिंग अपरिवर्तनीय है। यहाँ StringBuilder.appendस्ट्रिंग संघनन की तुलना में अधिक कुशल है।


public static String getRandomString(int length) {
       final String characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_+";
       StringBuilder result = new StringBuilder();
       while(length > 0) {
           Random rand = new Random();
           result.append(characters.charAt(rand.nextInt(characters.length())));
           length--;
       }
       return result.toString();
    }

3
यह पहले से कवर नहीं किए गए दर्जनों उत्तर कुछ भी नहीं जोड़ता है। और Randomलूप के प्रत्येक पुनरावृत्ति में एक नया उदाहरण बनाना अक्षम है।
इरिकसन

7
import java.util.Date;
import java.util.Random;

public class RandomGenerator {

  private static Random random = new Random((new Date()).getTime());

    public static String generateRandomString(int length) {
      char[] values = {'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','0','1','2','3',
               '4','5','6','7','8','9'};

      String out = "";

      for (int i=0;i<length;i++) {
          int idx=random.nextInt(values.length);
          out += values[idx];
      }
      return out;
    }
}

7
import java.util.*;
import javax.swing.*;
public class alphanumeric{
    public static void main(String args[]){
        String nval,lenval;
        int n,len;

        nval=JOptionPane.showInputDialog("Enter number of codes you require : ");
        n=Integer.parseInt(nval);

        lenval=JOptionPane.showInputDialog("Enter code length you require : ");
        len=Integer.parseInt(lenval);

        find(n,len);

    }
    public static void find(int n,int length) {
        String str1="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        StringBuilder sb=new StringBuilder(length);
        Random r = new Random();

        System.out.println("\n\t Unique codes are \n\n");
        for(int i=0;i<n;i++){
            for(int j=0;j<length;j++){
                sb.append(str1.charAt(r.nextInt(str1.length())));
            }
            System.out.println("  "+sb.toString());
            sb.delete(0,length);
        }
    }
}

7

वास्तव में "सरल" समाधान के बारे में इस तरह के किसी भी उत्तर को पसंद न करें: एस

मैं एक सरल के लिए जाना होगा;), शुद्ध जावा, एक लाइनर (एंट्रोपी यादृच्छिक स्ट्रिंग लंबाई और दिए गए सेट सेट पर आधारित है:

public String randomString(int length, String characterSet) {
    return IntStream.range(0, length).map(i -> new SecureRandom().nextInt(characterSet.length())).mapToObj(randomInt -> characterSet.substring(randomInt, randomInt + 1)).collect(Collectors.joining());
}

@Test
public void buildFiveRandomStrings() {
    for (int q = 0; q < 5; q++) {
        System.out.println(randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"));//charachterSet can basically be anything
    }
}

या (थोड़ा अधिक पठनीय पुराना तरीका)

public String randomString(int length, String characterSet) {
    StringBuilder sb = new StringBuilder(); //consider using StringBuffer if needed
    for (int i = 0; i < length; i++) {
        int randomInt = new SecureRandom().nextInt(characterSet.length());
        sb.append(characterSet.substring(randomInt, randomInt + 1));
    }
    return sb.toString();
}

@Test
public void buildFiveRandomStrings() {
    for (int q = 0; q < 5; q++) {
        System.out.println(randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")); //charachterSet can basically be anything
    }
}

लेकिन दूसरी ओर आप UUID के साथ भी जा सकते हैं जिसमें बहुत अच्छी एंट्रोपी है ( https://en.wikipedia.org/wiki/Universally_unique_identifier#Collisions ):

UUID.randomUUID().toString().replace("-", "")

उम्मीद है की वो मदद करदे।


6

आप "सरल" का उल्लेख करते हैं, लेकिन अगर कोई और ऐसी चीज़ की तलाश कर रहा है जो सुरक्षा की अधिक आवश्यकताओं को पूरा करती है, तो आप jpwgen पर एक नज़र डालना चाहते हैं । jpwgen को यूनिक्स में pwgen के बाद तैयार किया गया है , और यह बहुत ही विन्यास योग्य है।


धन्यवाद, इसे ठीक किया। तो यह कम से कम स्रोत है और लिंक वैध है। नकारात्मक पक्ष पर, ऐसा नहीं लगता है कि इसे थोड़ी देर में अपडेट किया गया है, हालांकि मुझे लगता है कि pwgen को हाल ही में काफी अपडेट किया गया है।
माइकल

4

आप अपने getLeastSignificantBits () संदेश के साथ UUID वर्ग का उपयोग 64bit रैंडम डेटा प्राप्त करने के लिए कर सकते हैं, फिर इसे एक मूलांक 36 संख्या में बदल सकते हैं (यानी एक स्ट्रिंग जिसमें 0-9, AZ) शामिल हैं:

Long.toString(Math.abs( UUID.randomUUID().getLeastSignificantBits(), 36));

इससे 13 वर्णों तक लंबी स्ट्रिंग प्राप्त होती है। हम यह सुनिश्चित करने के लिए Math.abs () का उपयोग करते हैं कि कोई ऋण चिह्न साइन इन नहीं हो रहा है।


2
दुनिया में आप यादृच्छिक बिट्स प्राप्त करने के लिए UUID का उपयोग क्यों करेंगे? सिर्फ उपयोग क्यों नहीं random.nextLong()? या भी Double.doubleToLongBits(Math.random())?
इक्केसन

4

आप निम्न कोड का उपयोग कर सकते हैं, यदि आपके पासवर्ड में अनिवार्य अक्षर विशेष वर्ण हैं:

private static final String NUMBERS = "0123456789";
private static final String UPPER_ALPHABETS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final String LOWER_ALPHABETS = "abcdefghijklmnopqrstuvwxyz";
private static final String SPECIALCHARACTERS = "@#$%&*";
private static final int MINLENGTHOFPASSWORD = 8;

public static String getRandomPassword() {
    StringBuilder password = new StringBuilder();
    int j = 0;
    for (int i = 0; i < MINLENGTHOFPASSWORD; i++) {
        password.append(getRandomPasswordCharacters(j));
        j++;
        if (j == 3) {
            j = 0;
        }
    }
    return password.toString();
}

private static String getRandomPasswordCharacters(int pos) {
    Random randomNum = new Random();
    StringBuilder randomChar = new StringBuilder();
    switch (pos) {
        case 0:
            randomChar.append(NUMBERS.charAt(randomNum.nextInt(NUMBERS.length() - 1)));
            break;
        case 1:
            randomChar.append(UPPER_ALPHABETS.charAt(randomNum.nextInt(UPPER_ALPHABETS.length() - 1)));
            break;
        case 2:
            randomChar.append(SPECIALCHARACTERS.charAt(randomNum.nextInt(SPECIALCHARACTERS.length() - 1)));
            break;
        case 3:
            randomChar.append(LOWER_ALPHABETS.charAt(randomNum.nextInt(LOWER_ALPHABETS.length() - 1)));
            break;
    }
    return randomChar.toString();

}

4

यहाँ AbacusUtil द्वारा एक लाइन कोड है

String.valueOf(CharStream.random('0', 'z').filter(c -> N.isLetterOrDigit(c)).limit(12).toArray())

यादृच्छिक का मतलब यह नहीं है कि यह अद्वितीय होना चाहिए। का उपयोग कर, अद्वितीय तार पाने के लिए:

N.uuid() // e.g.: "e812e749-cf4c-4959-8ee1-57829a69a80f". length is 36.
N.guid() // e.g.: "0678ce04e18945559ba82ddeccaabfcd". length is 32 without '-'



3
public static String randomSeriesForThreeCharacter() {
    Random r = new Random();
    String value="";
    char random_Char ;
    for(int i=0; i<10;i++)
    { 
        random_Char = (char) (48 + r.nextInt(74));
        value=value+random_char;
    }
    return value;
}

2
यह स्ट्रिंग समवर्ती अनावश्यक रूप से अक्षम है। और पागल इंडेंटेशन आपके कोड को लगभग अपठनीय बनाता है। यह जेमी के विचार के समान है, लेकिन खराब तरीके से निष्पादित किया गया है।
इरिकसन

3

मुझे लगता है कि यह यहाँ सबसे छोटा समाधान है, या लगभग सबसे छोटा है:

 public String generateRandomString(int length) {
    String randomString = "";

    final char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567890".toCharArray();
    final SecureRandom random = new SecureRandom();
    for (int i = 0; i < length; i++) {
        randomString = randomString + chars[random.nextInt(chars.length)];
    }

    return randomString;
}

कोड ठीक काम करता है। यदि आप इस पद्धति का उपयोग कर रहे हैं, तो मैं आपको 10 से अधिक वर्णों का उपयोग करने की सलाह देता हूं। टकराव 5 वर्ण / 30362 पुनरावृत्तियों पर होता है। इसमें 9 सेकंड का समय लगा।


3
public static String getRandomString(int length) {
        char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST".toCharArray();

        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            char c = chars[random.nextInt(chars.length)];
            sb.append(c);
        }
        String randomStr = sb.toString();

        return randomStr;
    }

1
बहुत अच्छे! लेकिन यह होना चाहिए lengthके बजाय chars.length: में पाश के लिए for (int i = 0; i < length; i++)
भस्मक

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