কিভাবে এলোমেলো আলফা-সংখ্যার স্ট্রিং তৈরি করতে হয়?


1741

আমি সিউডো-এলোমেলো আলফা-সংখ্যার স্ট্রিং তৈরি করতে একটি সাধারণ জাভা অ্যালগরিদম সন্ধান করছি। আমার পরিস্থিতিতে এটি একটি অনন্য আসর / কী সনাক্তকারী হিসাবে ব্যবহৃত হবে যা "সম্ভবত" 500K+প্রজন্মের তুলনায় অনন্য হয়ে উঠবে (আমার প্রয়োজনগুলিতে সত্যিকার অর্থে আরও অত্যাধিক কিছু প্রয়োজন হয় না)।

আদর্শভাবে, আমি আমার স্বতন্ত্রতার প্রয়োজনের উপর নির্ভর করে একটি দৈর্ঘ্য নির্দিষ্ট করতে সক্ষম হব। উদাহরণস্বরূপ, দৈর্ঘ্যের 12 টি উত্পন্ন উত্পন্ন স্ট্রিং এর মতো দেখতে পারে "AEYGF7K0DM1X"



58
এমনকি জন্মদিনের প্যারাডক্সটিকেও বিবেচনায় রেখে, আপনি যদি 12 টি বর্ণানুক্রমিক অক্ষর (62 টি মোট) ব্যবহার করেন তবে প্যারাডক্সে পৌঁছাতে আপনার এখনও 34 বিলিয়ন স্ট্রিংয়ের প্রয়োজন হবে। এবং জন্মদিনের প্যারাডক্স কোনওভাবেই সংঘর্ষের গ্যারান্টি দেয় না, এটি কেবল বলেছে এটি 50% এরও বেশি সুযোগের।
নাল ইউজারএক্সেপশন

4
@ নালুউজারএক্সেপশন 50% সাফল্যের সুযোগ (প্রতি চেষ্টা) অত্যধিক: 10 চেষ্টা করেও সাফল্যের হার 0.999। এটি এবং এই বিষয়টি যে আপনি 24 ঘন্টা মাথায় রেখে প্রচুর চেষ্টা করতে পারেন তার সাথে আপনার কমপক্ষে একটিরও অনুমান করার জন্য 34 বিলিয়ন স্ট্রিং লাগবে না। এই কারণেই কিছু সেশন টোকেন সত্যই, সত্যই দীর্ঘ হওয়া উচিত।
Pijusn

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);

সেশন সনাক্তকারী হিসাবে ব্যবহার করুন

সেশন শনাক্তকারীদের উত্পাদন করা যা সম্ভবত অনন্য বলে মনে হয় তা যথেষ্ট ভাল নয়, বা আপনি কেবল একটি সাধারণ কাউন্টার ব্যবহার করতে পারেন। যখন অনুমানযোগ্য সনাক্তকারী ব্যবহার করা হয় তখন আক্রমণকারীরা হাইজ্যাক সেশন করে।

দৈর্ঘ্য এবং সুরক্ষার মধ্যে টান রয়েছে। সংক্ষিপ্ত শনাক্তকারীদের অনুমান করা সহজ, কারণ সেখানে সম্ভাবনা কম। তবে আর শনাক্তকারীরা বেশি স্টোরেজ এবং ব্যান্ডউইথ ব্যবহার করেন। প্রতীকগুলির একটি বৃহত্তর সেট সাহায্য করে, তবে শনাক্তকারীদের ইউআরএল অন্তর্ভুক্ত করা থাকলে বা হাত দিয়ে পুনরায় প্রবেশ করা থাকলে এনকোডিংয়ের সমস্যা হতে পারে।

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

অবজেক্ট আইডেন্টিফায়ার হিসাবে ব্যবহার করুন

প্রতিটি অ্যাপ্লিকেশন সুরক্ষার প্রয়োজন হয় না। এলোমেলোভাবে অ্যাসাইনমেন্ট একাধিক সত্তার পক্ষে কোনও সমন্বয় বা পার্টিশন ছাড়াই ভাগ করে নেওয়া জায়গায় সনাক্তকারী উত্পন্ন করার কার্যকর উপায় হতে পারে। সমন্বয় ধীর হতে পারে, বিশেষত একটি ক্লাস্টারযুক্ত বা বিতরণ পরিবেশে, এবং সত্ত্বাগুলি যখন খুব ছোট বা খুব বড় শেয়ারগুলি সমাপ্ত হয় তখন একটি স্থান বিভাজন সমস্যা তৈরি করে।

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

প্রত্যাশিত মোট শনাক্তকারীদের সংখ্যার ভিত্তিতে সংঘর্ষগুলি তৈরি করতে যথেষ্ট দীর্ঘ এমন শনাক্তকারীদের ব্যবহার করার জন্যও যত্ন নেওয়া উচিত। এটি "জন্মদিনের প্যারাডক্স" হিসাবে উল্লেখ করা হয়। সংঘর্ষের সম্ভাবনা, পি , প্রায় আনুমানিক 2 2 / (2q x ), যেখানে n আসলে উত্পাদিত শনাক্তকারীর সংখ্যা, q বর্ণমালার পৃথক চিহ্নগুলির সংখ্যা এবং x শনাক্তকারীদের দৈর্ঘ্য। এটি খুব কম সংখ্যক হওয়া উচিত, যেমন 2 ‑50 বা তার চেয়ে কম।

এটি কাজ করে দেখায় যে 500 কে 15-চরিত্র শনাক্তকারীদের মধ্যে সংঘর্ষের সম্ভাবনা প্রায় 2 ‑52 , যা সম্ভবত মহাজাগতিক রশ্মি থেকে সনাক্ত করা ত্রুটিগুলির চেয়ে কম সম্ভাবনা রয়েছে etc.

ইউইউডিগুলির সাথে তুলনা

তাদের স্পেসিফিকেশন অনুসারে, ইউআইডিগুলি অনুমানযোগ্য হিসাবে নকশাকৃত নয় এবং সেশন শনাক্তকারী হিসাবে ব্যবহার করা উচিত নয়

তাদের মানক বিন্যাসে ইউআইডিগুলি প্রচুর স্থান নেয়: কেবলমাত্র ইন্ট্রপির 122 বিটের জন্য 36 টি অক্ষর। (একটি "এলোমেলো" ইউআইডি এর সমস্ত বিট এলোমেলোভাবে নির্বাচন করা হয় না)) একটি এলোমেলোভাবে বেছে নেওয়া আলফানিউমেরিক স্ট্রিং মাত্র 21 টি অক্ষরে আরও এনট্রপি প্যাক করে।

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


6
আপনার যদি নিজের মধ্যে ফাঁকির প্রয়োজন হয় তবে আপনি রেজিটক্স অদলবদল করতে লাইনটির .replaceAll("\\d", " ");শেষ প্রান্তে return new BigInteger(130, random).toString(32);যেতে পারেন। এটি শূন্যস্থান সহ সমস্ত অঙ্ককে প্রতিস্থাপন করে। আমার জন্য দুর্দান্ত কাজ করে: আমি এটিকে ফ্রন্ট-এন্ড
লোরেম ইপসামের

4
@ উইজহোন এটি একটি ভাল ধারণা। আপনি দ্বিতীয় পদ্ধতির সাথে অনুরূপ কিছু করতে পারেন, এর থেকে অঙ্কগুলি সরিয়ে symbolsএবং পরিবর্তে একটি স্থান ব্যবহার করে; প্রতীকগুলিতে ফাঁকের সংখ্যা পরিবর্তন করে (সংক্ষিপ্ত শব্দের আরও উপস্থিতি) আপনি গড় "শব্দ" দৈর্ঘ্যটি নিয়ন্ত্রণ করতে পারেন। সত্যিকার অর্থে শীর্ষস্থানীয় জাল পাঠ্য সমাধানের জন্য, আপনি একটি মার্কভ চেইন ব্যবহার করতে পারেন!
এরিকসন

4
এই সনাক্তকারীরা এলোমেলোভাবে একটি নির্দিষ্ট আকারের স্থান থেকে নির্বাচন করা হয়। তারা 1 অক্ষর দীর্ঘ হতে পারে। আপনি যদি একটি নির্দিষ্ট দৈর্ঘ্য চান, আপনি ভেরিয়েবলের SecureRandomজন্য বরাদ্দ একটি উদাহরণ সহ দ্বিতীয় সমাধানটি ব্যবহার করতে পারেন random
এরিকসন

15
.ToString (36) এর চেয়ে কেন .toString (32)?
এজেন

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
ইউআইডি ক্লাসটি কার্যকর। যাইহোক, তারা আমার উত্তরগুলি দ্বারা উত্পাদিত শনাক্তকারীদের মতো কমপ্যাক্ট নয়। এটি ইউআরএলগুলিতে উদাহরণস্বরূপ, একটি সমস্যা হতে পারে। আপনার প্রয়োজনের উপর নির্ভর করে।
ইরিকসন

6
@ রাগস - লক্ষ্যটি হচ্ছে আলফা-সংখ্যার স্ট্রিং। কীভাবে কোনও সম্ভাব্য বাইটে আউটপুট প্রশস্ত করা যায়?
এরিকসন

72
আরএফসি 4122 অনুসারে ইউইউডিএসকে টোকেন হিসাবে ব্যবহার করা একটি খারাপ ধারণা: অনুমান করবেন না যে ইউআইডিগুলি অনুমান করা শক্ত are এগুলি সুরক্ষার ক্ষমতা হিসাবে ব্যবহার করা উচিত নয় (উদাহরণস্বরূপ যাদের পরিচয় কেবলমাত্র দখল অ্যাক্সেস দেয়)। একটি পূর্বাভাসযোগ্য এলোমেলো সংখ্যা উত্স পরিস্থিতি আরও বাড়িয়ে তুলবে। 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। পাসওয়ার্ড যদি কোনও সার্ভারে উত্পন্ন হয় তবে এটি সময় আক্রমণে ঝুঁকিপূর্ণ হতে পারে।
ফেনা

8
আমি ছোট হাতগুলিও যুক্ত করতাম: AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";এবং কিছু অন্যান্য অনুমোদিত অক্ষর।
এসিভি

1
static Random rnd = new Random();পদ্ধতির ভিতরে রাখি না কেন ?
মাইক্রো

4
@ মাইক্রোআর কি 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

যেহেতু কমন্স-ল্যাং ৩.6 রয়েছে, RandomStringUtilsহ্রাস করা হয়েছে।


22
শুধু মাধ্যমে লাগছিল হয়েছে উল্লেখ বর্গ এর Apache Commons Lang 3.3.1গ্রন্থাগার - এবং এটি শুধুমাত্র ব্যবহার করা হয় java.util.Randomর্যান্ডম ক্রম প্রদান, তাই এটি উত্পাদক হয় অনিরাপদ সিকোয়েন্স
ইউরি নাকনটেকায়ি

16
র্যান্ডম স্ট্রিং ইউটিসগুলি ব্যবহার করার সময় আপনি সিকিউরআরন্ডম ব্যবহার করেছেন তা নিশ্চিত করুন:public static java.lang.String random(int count, int start, int end, boolean letters, boolean numbers, @Nullable char[] chars, java.util.Random random)
রুস্লানস ইউরলভস

ব্যবহার করবেন না. এটি অনিরাপদ ক্রম তৈরি করে !
প্যাট্রিক ফ্যাভের

109

আপনি এটির জন্য অ্যাপাচি লাইব্রেরি ব্যবহার করতে পারেন: র্যান্ডমস্ট্রিংআটিলস

RandomStringUtils.randomAlphanumeric(20).toUpperCase();

18
@ কামিল, আমি র্যান্ডম স্ট্রিং ইউটিলসের জন্য উত্স কোডটি দেখেছি এবং এতে java.util.Random এর উদাহরণ ব্যবহার করা হয়েছে argu Java.util.Random এর ডকুমেন্টেশন বলছে যে কোনও বীজ সরবরাহ না করা থাকলে এটি বর্তমান সিস্টেম সময় ব্যবহার করে। এর অর্থ হ'ল এটি সেশন শনাক্তকারী / কীগুলির জন্য ব্যবহার করা যাবে না কারণ কোনও আক্রমণকারী সহজেই পূর্বাভাস দিতে পারে যে উত্পন্ন সেশন শনাক্তকারীরা কোনও নির্দিষ্ট সময়টিতে কী।
ইনশাল্লাহ

36
@ ইনশাল্লাহ: আপনি (অকারণে) সিস্টেমকে ওভাররিঞ্জাইনিং করছেন। যদিও আমি একমত যে এটি সময় হিসাবে বীজ হিসাবে ব্যবহার করে, আক্রমণকারীটির আসলে কী চান তা পেতে নিম্নলিখিত তথ্যগুলিতে অ্যাক্সেস করতে হবে 1. কোডটি বীজ করার সময় সঠিক মিলিসেকেন্ডের সময় ২. এখন পর্যন্ত সংঘটিত কলগুলির সংখ্যা ৩. তাঁর নিজের কলের জন্য পারমাণবিকতা (যাতে এই সংখ্যাটি এতদূর চলে আসে) আপনার আক্রমণকারীটির যদি এই তিনটি জিনিসই থাকে তবে আপনার হাতে আরও বড় সমস্যা রয়েছে ...
অজিত গঙ্গা

3
গ্রেড নির্ভরতা: compile 'commons-lang:commons-lang:2.6'
younes0

4
@ অজিত এই সত্য নয়। আপনি এর আউটপুট থেকে এলোমেলো সংখ্যা জেনারেটরের অবস্থা অর্জন করতে পারেন। কোনও আক্রমণকারী যদি এলোমেলো এপিআই টোকেন তৈরি করতে কয়েক হাজার কল উত্পন্ন করতে পারে তবে আক্রমণকারী ভবিষ্যতের সমস্ত এপিআই টোকেন পূর্বাভাস দিতে সক্ষম হবে।
থমাস গ্রেনার

3
@ অজিতগঙ্গা ওভার ইঞ্জিনিয়ারিংয়ের সাথে কিছুই করার নেই। আপনি যদি সেশন আইডস তৈরি করতে চান তবে আপনার একটি ক্রিপ্টোগ্রাফিক সিউডো র্যান্ডম জেনারেটর দরকার need বীজ হিসাবে সময় ব্যবহার করে প্রতিটি প্রান অনুমানযোগ্য এবং ডেটার জন্য এটি খুব অনিরাপদ যা অনির্দেশ্য হতে পারে। শুধু ব্যবহার করুন SecureRandomএবং আপনি ভাল।
প্যাট্রিক ফ্যাভের

105

এক লাইনে:

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

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


9
তবে কেবল 6 টি চিঠি :(
মোশে রেভাঃ

2
এটি আমাকে খুব সাহায্য করেছে তবে কেবলমাত্র হেক্সাডেসিমাল সংখ্যা :(
উদ্বিগ্ন

@ জিপ্পক্সার, আপনি একাধিকবার সমালোচনা করতে পারেন =)
ড্যানিয়েল.ব্যাব্রিন

7
ওপির উদাহরণ নীচের স্ট্রিংকে উদাহরণ হিসাবে দেখিয়েছে AEYGF7K0DM1Xযা হেক্সাডেসিমাল নয়। এটি আমাকে চিন্তিত করে যে লোকেরা হেক্সাডেসিমালের সাথে প্রায়শই অক্ষরগুলিকে ভুল করে। এগুলো এক জিনিস না.
hfontanez

6
এটি স্ট্রিং দৈর্ঘ্যের চেয়ে কম এলোমেলো কারণ এটি 0 এবং 1 এর মধ্যে Math.random()উত্পাদন করে double, তাই খাঁটি অংশটি বেশিরভাগ অব্যবহৃত থাকে। এই কুরুচিপূর্ণ হ্যাক পরিবর্তে random.nextLongএকটি এলোমেলো জন্য ব্যবহার করুন long
মার্টিনাস

80

এটি কোনও বাহ্যিক গ্রন্থাগার ছাড়া সহজেই অর্জনযোগ্য।

1. ক্রিপ্টোগ্রাফিক সিউডো এলোমেলো ডেটা জেনারেশন

প্রথমে আপনার একটি ক্রিপ্টোগ্রাফিক পিআরএনজি দরকার। জাভা এর SecureRandomজন্য রয়েছে এবং সাধারণত মেশিনে সেরা এনট্রপি উত্স ব্যবহার করে (উদাঃ /dev/random)। এখানে আরও পড়ুন।

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

দ্রষ্টব্য: SecureRandom এলোমেলো বাইট তৈরির জাভাতে সবচেয়ে ধীরতম তবে সবচেয়ে সুরক্ষিত উপায়। তবে আমি এখানে পারফরম্যান্স বিবেচনা না করার পরামর্শ দিচ্ছি কারণ আপনার সেকেন্ডে কয়েক মিলিয়ন টোকেন তৈরি করতে না পারলে এটি আপনার আবেদনের উপরে সাধারণত কোন প্রভাব ফেলে না।

২. সম্ভাব্য মানগুলির প্রয়োজনীয় স্থান

এরপরে আপনাকে সিদ্ধান্ত নিতে হবে আপনার টোকেনটি "কতটা অনন্য" হতে হবে। এনট্রপির বিবেচনার সম্পূর্ণ এবং একমাত্র বিষয় হ'ল সিস্টেমটি বর্বর বাহিনীর আক্রমণগুলিকে প্রতিহত করতে পারে তা নিশ্চিত করা: সম্ভাব্য মানের জায়গাগুলি অবশ্যই এত বড় হওয়া উচিত যে কোনও আক্রমণকারী কেবল অ-হাস্যকর সময় 1 -তে মানগুলির একটি নগন্য অনুপাত চেষ্টা করতে পারে । এলোমেলো হিসাবে অনন্য শনাক্তকারীদের UUIDএন্টারোপি 122 বিট থাকে (যেমন 2 ^ 122 = 5.3x10 ^ 36) - সংঘর্ষের সম্ভাবনা "* (...) হ'ল সেখানে এক মিলিয়ন ডুপ্লিকেশন হওয়ার সম্ভাবনা রয়েছে, 103 ট্রিলিয়ন সংস্করণ 4 ইউআইডিগুলি অবশ্যই 2 " উত্পন্ন করা উচিত । আমরা 128 বিট বেছে নেব যেহেতু এটি 16 বাইটে হুবহু ফিট করে এবং এটি যথেষ্ট পর্যাপ্ত হিসাবে দেখা যায়মূলত প্রতিটি জন্য অনন্য, তবে সবচেয়ে চরম, ক্ষেত্রে ব্যবহার এবং আপনি নকল সম্পর্কে চিন্তা করতে হবে না। জন্মদিনের সমস্যার সহজ বিশ্লেষণ সহ এন্ট্রপির একটি সাধারণ তুলনা টেবিল এখানে ।

টোকেন মাপের তুলনা

সাধারণ প্রয়োজনীয়তার জন্য 8 বা 12 বাইটের দৈর্ঘ্য যথেষ্ট হতে পারে তবে 16 বাইটের সাহায্যে আপনি "নিরাপদ দিকে" রয়েছেন।

এবং এটি মূলত এটি। শেষ কথাটি এনকোডিং সম্পর্কে চিন্তা করা যাতে এটি মুদ্রণযোগ্য পাঠ্য হিসাবে উপস্থাপিত হতে পারে (পড়ুন, ক String)।

3. টেক্সট এনকোডিং বাইনারি

সাধারণ এনকোডিংগুলির মধ্যে রয়েছে:

  • Base64প্রতিটি অক্ষর একটি 33% ওভারহেড তৈরি 6 বিটকে এনকোড করে। সৌভাগ্যবশত সেখানে মান বাস্তবায়নের হয় জাভা 8+ এবং অ্যান্ড্রয়েড । পুরানো জাভা দিয়ে আপনি অসংখ্য তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করতে পারেন । আপনি যদি চান আপনার টোকেনগুলি ইউআরএল নিরাপদে থাকে তবে আরএফসি 4648 (যা সাধারণত বেশিরভাগ বাস্তবায়ন দ্বারা সমর্থিত) এর ইউআরএল-নিরাপদ সংস্করণ ব্যবহার করুন use প্যাডিং সহ 16 বাইট এনকোডিং উদাহরণ:XfJhfv3C0P6ag7y9VQxSbw==

  • Base32প্রতিটি চরিত্র 5 বিটকে 40% ওভারহেড তৈরি করে এনকোড করে। এই ব্যবহার করবে A-Zএবং 2-7এটা যুক্তিসঙ্গতভাবে স্থান দক্ষ যখন কেস-অবশ আলফা-সাংখ্যিক হচ্ছে করে। জেডিকে কোনও মানক বাস্তবায়ন নেই । প্যাডিং ছাড়াই 16 বাইট এনকোডিংয়ের উদাহরণ:WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16(হেক্স) প্রতিটি অক্ষর 4 বিট এনকোড করে 4 বিট প্রতি বাইটের প্রয়োজন (যেমন 16 বাইট দৈর্ঘ্যের 32 টি স্ট্রিং তৈরি করে)। অতএব হেক্স কম জায়গা থেকেও কার্যকারী Base32কিন্তু যেহেতু এটি শুধুমাত্র ব্যবহার বেশিরভাগ ক্ষেত্রেই (URL) এ ব্যবহারের জন্য নিরাপদ 0-9এবং Aকরতে F। উদাহরণ 16 বাইট এনকোডিং: 4fa3dd0f57cb3bf331441ed285b27735এখানে হেক্সে রূপান্তর সম্পর্কে একটি SO আলোচনা দেখুন।

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

4. সংক্ষিপ্তসার এবং উদাহরণ

  • ব্যবহার SecureRandom
  • সম্ভাব্য মানগুলির কমপক্ষে 16 বাইট (2 ^ 128) ব্যবহার করুন
  • আপনার প্রয়োজনীয়তা অনুসারে এনকোড করুন (সাধারণত hexবা আপনার base32যদি এটি আলফা-সংখ্যাসূচক প্রয়োজন হয়)

না

  • ... আপনার বাড়ির ব্রু এনকোডিংটি ব্যবহার করুন: অন্যদের জন্য আরও ভাল রক্ষণাবেক্ষণযোগ্য এবং পাঠযোগ্য if
  • ... ইউইউডি ব্যবহার করুন: এলোমেলোতার কোনও গ্যারান্টি নেই; আপনি এনট্রপির 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

উদাহরণ: সম্পর্কিত সমস্যা - আপনার বর্তমান আইডি সংরক্ষণ করুন

আপনার যদি ইতিমধ্যে কোনও আইডি থাকে তবে আপনি (যেমন 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)
ফ্র্যাঙ্কোসার

ইঙ্গিতটির জন্য ট্যাঙ্কস @ ফ্র্যাঙ্কোসর, আমি কোড উদাহরণটি সম্পাদনা করেছি
প্যাট্রিক ফ্যাভ্রে

import java.security.SecureRandom;এবং import java.math.BigInteger;উদাহরণটি কাজ করা প্রয়োজন, কিন্তু এটি দুর্দান্ত কাজ করে!
আরেকটিএম

ভাল উত্তর তবে / ডেভ / এলোমেলো হ'ল একটি ব্লকিং পদ্ধতি যা এন্ট্রপি খুব কম হলে এটি ব্লক করার বিন্দুতে ধীর হয়। আরও ভাল এবং অবরুদ্ধকরণ পদ্ধতি হ'ল / ডেভ / ইউরানডম। এটি <জ্রে> / লিব / সুরক্ষা / জাভা.সিকিউরিটির মাধ্যমে কনফিগার করা যেতে পারে এবং সুরক্ষিত সেট সেট করা যেতে পারে =সূত্র = ফাইল: / দেব / // ইউরানডম
মুজাম্মিল

@ মুজাম্মিল দেখুন 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 ব্যবহার করা সম্ভব?
iwein

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বা nextLong। প্রয়োজনে স্যুইচ করুন SecureRandom
মার্টিনাস

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 রেকর্ডের জন্য সহজ যথেষ্ট পরিমাণ এলোমেলো পরিমাণ রয়েছে।



31

একটি সংক্ষিপ্ত এবং সহজ সমাধান, তবে কেবল ছোট এবং সংখ্যা ব্যবহার করে:

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

৩ base বেসের আকারটি প্রায় 12 অঙ্কের এবং সেভাবে আর উন্নতি করা যায় না। অবশ্যই আপনি একাধিক উদাহরণ সংযোজন করতে পারেন।


11
কেবল মনে রাখবেন, ফলাফলের বিয়োগ চিহ্নের 50% সম্ভাবনা রয়েছে! সুতরাং আপনি একটি বিয়োগ চিহ্নটি না চাইলে একটি ম্যাথ.অ্যাবস () এ r.nextLong () ব্যবহার করা যেতে পারে: Long.toString(Math.abs(r.nextLong()), 36);
রায় হুলহা

5
@ রায়হুলহা: আপনি যদি বিয়োগ চিহ্নটি না চান তবে আপনার এটি কেটে দেওয়া উচিত, কারণ আশ্চর্যজনকভাবে ম্যাথ.এবস লংয়ের জন্য একটি নেতিবাচক মান ফেরায়।
ব্যবহারকারী অজানা

আকর্ষণীয় ম্যাথ.অ্যাবস নেতিবাচক ফিরে। আরও এখানে: bmaurer.blogspot.co.nz/2006/10/…
ফিল

1
absসর্বাধিক তাৎপর্যপূর্ণ বিট সাফ করার জন্য বিটওয়াস অপারেটর ব্যবহার করে সমস্যাটি সমাধান করা হয়েছে। এটি সমস্ত মানের জন্য কাজ করবে।
রেডিওডেফ 23

1
@ রেডিওডেফ এটিই মূলত @ ইউজার টাউন বলেছে। আমি মনে করি আপনি করতে পারেন << 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, আয, এজেড) এখানে যৌক্তিক
ড্যান

12

ইউআইডিগুলি ব্যবহার করা নিরাপত্তাহীন, কারণ ইউইউডিটির কিছু অংশ এলোমেলো নয়। @ এরিকসনের পদ্ধতিটি খুব ঝরঝরে, তবে একই দৈর্ঘ্যের স্ট্রিং তৈরি করে না। নিম্নলিখিত স্নিপেট যথেষ্ট হওয়া উচিত:

/*
 * 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। আসুন দৈর্ঘ্য 1 এর এলোমেলো স্ট্রিংয়ের সাধারণ কেস ধরে নেওয়া যাক, তাই একটি এলোমেলো অক্ষর। সমস্ত অঙ্ক 0-9 এবং অক্ষর এজেড সহ একটি এলোমেলো অক্ষর পেতে, প্রতিটি বর্ণের একটি পেতে আমাদের 0 এবং 35 এর মধ্যে একটি এলোমেলো সংখ্যা প্রয়োজন need BigIntegerএকটি এলোমেলো সংখ্যা জেনার জন্য কনস্ট্রাক্টর সরবরাহ করে, পরিসীমাতে অভিন্নভাবে বিতরণ করা হয় 0 to (2^numBits - 1)। দুর্ভাগ্যক্রমে 35 এমন কোনও সংখ্যা নয় যা 2 ^ numBits দ্বারা প্রাপ্ত হতে পারে - ১. সুতরাং আমাদের কাছে দুটি বিকল্প রয়েছে: হয় হয় 2^5-1=31বা সাথে যান 2^6-1=63। আমরা যদি চয়ন করতে 2^6পারি তবে আমরা প্রচুর "আনসেসারি" / "দীর্ঘ" সংখ্যা পাব। সুতরাং 2^5আমরা আরও 4 টি অক্ষর (ডাব্লু ডাব্লু) ছাড়িয়ে দিলে আরও ভাল বিকল্প। এখন একটি নির্দিষ্ট দৈর্ঘ্যের একটি স্ট্রিং উত্পন্ন করতে, আমরা কেবল একটি ব্যবহার করতে পারি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);
        }
    }
}

আমি মনে করি না ডুপ্লিকেট টোকেনগুলির জন্য ব্যর্থ হওয়া ন্যায়সঙ্গত, যা নিখুঁতভাবে সম্ভাবনার উপর ভিত্তি করে।
থম উইগার্স

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
    }
}

তবে অন্যদিকে আপনি ইউআইডির সাথেও যেতে পারেন যার একটি দুর্দান্ত এনট্রপি রয়েছে ( https://en.wikedia.org/wiki/Universally_unique_ شناختফায়ার # কল্পনা ):

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

আশা করি এইটি কাজ করবে.


6

আপনি "সিম্পল" উল্লেখ করেছেন, তবে অন্য কেউ যদি আরও কড়া সুরক্ষার প্রয়োজনীয়তা পূরণ করে এমন কিছু সন্ধান করে, আপনি জেপিডিজেন একবার দেখে নিতে পারেন । jpwgen ইউনিক্সে pwgen এর পরে মডেল করা হয়েছে এবং এটি খুব কনফিগারযোগ্য।


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

4

আপনি ইউইউডি ক্লাসটি তার getLeastSignificantBits () বার্তার সাহায্যে om৪ বিট র্যান্ডম ডেটা পেতে ব্যবহার করতে পারেন, তারপরে এটিকে একটি র‌্যাডিক্স ৩ number সংখ্যায় রূপান্তর করুন (অর্থাত্ ০-৯, AZ সমন্বিত একটি স্ট্রিং):

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

এটি 13 টি অক্ষর দীর্ঘ পর্যন্ত একটি স্ট্রিং দেয় yield আমরা মাইন.এবস () ব্যবহার করে এটি নিশ্চিত করে রাখি যে সেখানে কোনও বিয়োগ চিহ্ন স্নিগ্ধ করা হচ্ছে না।


2
বিশ্বে আপনি ইউএনইউডি এলোমেলো বিটগুলি কেন ব্যবহার করবেন? শুধু ব্যবহার 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

অ্যাবাকাসটিলের একটি লাইন কোড এখানে

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++)
দাহনযন্ত্র

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.