سؤال

لقد كنت أبحث عن أ بسيط خوارزمية جافا لإنشاء سلسلة أبجدية رقمية شبه عشوائية.في حالتي، سيتم استخدامه كمعرف فريد للجلسة/المفتاح والذي "من المحتمل" أن يكون فريدًا 500K+ الجيل (احتياجاتي لا تتطلب حقًا أي شيء أكثر تعقيدًا).

من الناحية المثالية، سأكون قادرًا على تحديد الطول وفقًا لاحتياجاتي الفريدة.على سبيل المثال، قد تبدو السلسلة التي تم إنشاؤها بطول 12 شيئًا كهذا "AEYGF7K0DM1X".

هل كانت مفيدة؟

المحلول

خوارزمية

لإنشاء سلسلة عشوائية، قم بتسلسل الأحرف المرسومة عشوائيًا من مجموعة الرموز المقبولة حتى تصل السلسلة إلى الطول المطلوب.

تطبيق

إليك بعض التعليمات البرمجية البسيطة والمرنة جدًا لإنشاء معرفات عشوائية. اقرأ المعلومات التالية للحصول على ملاحظات التطبيق الهامة.

import java.security.SecureRandom;
import java.util.Locale;
import java.util.Objects;
import java.util.Random;

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

استخدم كمعرفات الجلسة

إن إنشاء معرفات الجلسة التي من المحتمل أن تكون فريدة ليس جيدًا بما فيه الكفاية، أو يمكنك فقط استخدام عداد بسيط.يقوم المهاجمون باختطاف الجلسات عند استخدام معرفات يمكن التنبؤ بها.

هناك توتر بين الطول والأمن.من السهل تخمين المعرفات الأقصر، لأن الاحتمالات أقل.لكن المعرفات الأطول تستهلك المزيد من مساحة التخزين وعرض النطاق الترددي.تساعد مجموعة أكبر من الرموز، ولكنها قد تسبب مشاكل في التشفير إذا تم تضمين المعرفات في عناوين URL أو إعادة إدخالها يدويًا.

يجب أن يأتي المصدر الأساسي للعشوائية، أو الإنتروبيا، لمعرفات الجلسة من مولد أرقام عشوائي مصمم للتشفير.ومع ذلك، قد يكون تهيئة هذه المولدات في بعض الأحيان مكلفًا أو بطيئًا من الناحية الحسابية، لذا يجب بذل الجهد لإعادة استخدامها عندما يكون ذلك ممكنًا.

استخدم كمعرفات للكائنات

ليس كل تطبيق يتطلب الأمن.يمكن أن يكون التعيين العشوائي وسيلة فعالة لكيانات متعددة لإنشاء معرفات في مساحة مشتركة دون أي تنسيق أو تقسيم.يمكن أن يكون التنسيق بطيئًا، خاصة في بيئة مجمعة أو موزعة، ويتسبب تقسيم المساحة في حدوث مشكلات عندما ينتهي الأمر بالكيانات بمشاركات صغيرة جدًا أو كبيرة جدًا.

يجب حماية المعرفات التي تم إنشاؤها دون اتخاذ تدابير تجعلها غير قابلة للتنبؤ بها بوسائل أخرى إذا كان المهاجم قادرًا على عرضها ومعالجتها، كما يحدث في معظم تطبيقات الويب.يجب أن يكون هناك نظام ترخيص منفصل يحمي الكائنات التي يمكن للمهاجم تخمين معرفها دون إذن الوصول.

يجب أيضًا توخي الحذر عند استخدام معرفات طويلة بما يكفي لجعل الاصطدامات غير محتملة نظرًا للعدد الإجمالي المتوقع للمعرفات.ويشار إلى هذا باسم "مفارقة عيد الميلاد". احتمال الاصطدام, ص, ، هو ما يقرب من ن2/(2سس)، أين ن هو عدد المعرفات التي تم إنشاؤها بالفعل، س هو عدد الرموز المميزة في الأبجدية، و س هو طول المعرفات.يجب أن يكون هذا رقمًا صغيرًا جدًا، مثل 2‑50 او اقل.

يوضح حل ذلك أن فرصة الاصطدام بين المعرفات المكونة من 500 ألف مكونة من 15 حرفًا تبلغ حوالي 2‑52, ، وهو على الأرجح أقل احتمالاً من الأخطاء غير المكتشفة من الأشعة الكونية، وما إلى ذلك.

مقارنة مع UUIDs

وفقًا لمواصفاتها، لم يتم تصميم UUIDs بحيث لا يمكن التنبؤ بها، و لا يجب يمكن استخدامها كمعرفات الجلسة.

تشغل UUIDs بتنسيقها القياسي مساحة كبيرة:36 حرفًا مقابل 122 بت فقط من الإنتروبيا.(لا يتم تحديد جميع أجزاء UUID "العشوائية" بشكل عشوائي.) تحتوي السلسلة الأبجدية الرقمية المختارة عشوائيًا على المزيد من الإنتروبيا في 21 حرفًا فقط.

UUIDs ليست مرنة؛لديهم هيكل وتخطيط موحد.هذه هي فضيلتهم الرئيسية وكذلك نقطة ضعفهم الرئيسية.عند التعاون مع طرف خارجي، قد يكون التوحيد الذي توفره UUIDs مفيدًا.للاستخدام الداخلي البحت، يمكن أن تكون غير فعالة.

نصائح أخرى

توفر Java طريقة للقيام بذلك مباشرة.إذا كنت لا تريد الشرطات، فمن السهل نزعها.مجرد استخدام 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
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();
}

إذا كنت سعيدًا باستخدام فئات Apache، فيمكنك استخدامها 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 تم إهماله.

في سطر واحد:

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

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

يمكنك استخدام مكتبة Apache لهذا: RandomStringUtils

RandomStringUtils.randomAlphanumeric(20).toUpperCase();

يمكن تحقيق ذلك بسهولة دون أي مكتبات خارجية.

1.تشفير البيانات العشوائية الزائفة

تحتاج أولاً إلى PRNG مشفر.جافا لديها SecureRandom لذلك عادةً ما يستخدم أفضل مصدر للإنتروبيا على الجهاز (على سبيل المثال. /dev/random) . اقرأ المزيد هنا.

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

ملحوظة: SecureRandom هي الطريقة الأبطأ والأكثر أمانًا في Java لإنشاء بايتات عشوائية.ومع ذلك، أوصي بعدم النظر في الأداء هنا لأنه عادةً لا يكون له أي تأثير حقيقي على تطبيقك إلا إذا كان عليك إنشاء ملايين الرموز المميزة في الثانية.

2.المساحة المطلوبة للقيم المحتملة

بعد ذلك عليك أن تقرر "مدى التفرد" الذي يجب أن يكون عليه الرمز المميز الخاص بك.النقطة الأساسية والوحيدة للنظر في الإنتروبيا هي التأكد من أن النظام قادر على مقاومة هجمات القوة الغاشمة:يجب أن تكون مساحة القيم المحتملة كبيرة جدًا بحيث لا يتمكن أي مهاجم من تجربة سوى نسبة ضئيلة من القيم في وقت غير مثير للسخرية1.معرفات فريدة مثل عشوائي UUID لديك 122 بت من الانتروبيا (أي.2^122 = 5.3x10^36) - فرصة الاصطدام هي "*(...) لكي تكون هناك فرصة واحدة في المليار للتكرار، يجب إنشاء 103 تريليون الإصدار 4 من UUIDs2". سنختار 128 بت لأنه يتناسب تمامًا مع 16 بايت وينظر إليه على أنه كافية للغاية لكونها فريدة من نوعها لكل حالات الاستخدام، ولكن الأكثر تطرفًا، ولا يتعين عليك التفكير في التكرارات.فيما يلي جدول مقارنة بسيط للإنتروبيا يتضمن تحليلًا بسيطًا للإنتروبيا مشكلة عيد ميلاد.

comparison of token sizes

بالنسبة للمتطلبات البسيطة، قد يكفي طول 8 أو 12 بايت، ولكن مع 16 بايت فأنت في "الجانب الآمن".

وهذا هو الأساس.آخر شيء هو التفكير في التشفير بحيث يمكن تمثيله كنص قابل للطباعة (اقرأ، أ String).

3.ثنائي لترميز النص

تتضمن الترميزات النموذجية ما يلي:

  • Base64 يقوم كل حرف بتشفير 6 بت مما يؤدي إلى زيادة الحمل بنسبة 33%.لحسن الحظ هناك تطبيقات قياسية في جافا 8+ و ذكري المظهر.مع Java الأقدم، يمكنك استخدام أي من العديد من مكتبات الطرف الثالث.إذا كنت تريد أن تكون الرموز المميزة الخاصة بك آمنة لعنوان url، فاستخدم عنوان URL آمن إصدار RFC4648 (والذي عادةً ما يكون مدعومًا من قبل معظم التطبيقات).مثال لترميز 16 بايت مع الحشو: XfJhfv3C0P6ag7y9VQxSbw==

  • Base32 يقوم كل حرف بتشفير 5 بت مما يؤدي إلى زيادة الحمل بنسبة 40%.هذا سوف يستخدم A-Z و 2-7 مما يجعلها فعالة في المساحة بشكل معقول مع كونها غير حساسة لحالة الأحرف.لا يوجد التنفيذ القياسي في JDK.مثال لترميز 16 بايت بدون الحشو: WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16 (ست عشري) كل حرف يشفر 4 بت ويتطلب حرفين لكل بايت (على سبيل المثال.16 بايت إنشاء سلسلة بطول 32).لذلك فإن السداسية أقل كفاءة في استخدام المساحة من Base32 ولكنه آمن للاستخدام في معظم الحالات (url) لأنه يستخدم فقط 0-9 و A ل F.مثال لترميز 16 بايت: 4fa3dd0f57cb3bf331441ed285b27735. راجع مناقشة SO حول التحويل إلى ست عشري هنا.

ترميزات إضافية مثل قاعدة85 والغريبة قاعدة122 توجد بكفاءة مساحة أفضل/أسوأ.يمكنك إنشاء الترميز الخاص بك (وهو ما تفعله معظم الإجابات في هذا الموضوع بشكل أساسي) ولكنني أنصح بعدم القيام بذلك، إذا لم تكن لديك متطلبات محددة للغاية.يرى المزيد من مخططات التشفير في مقالة ويكيبيديا.

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

مثال:مولد الرمز المميز Base64 (عنوان URL الآمن)

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

مثال:أداة جافا CLI

إذا كنت تريد أداة cli جاهزة للاستخدام، فيمكنك استخدام النرد: https://github.com/patrickfav/dice

استخدام دولار يجب أن تكون بسيطة مثل:

// "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

وهنا في جافا:

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

والمثير للدهشة أن أحداً هنا لم يقترح ذلك ولكن:

import java.util.UUID

UUID.randomUUID().toString();

سهل.

الاستفادة من ذلك هي أن UUIDs لطيفة وطويلة ومضمونة أنه من المستحيل تقريبًا الاصطدام بها.

ويكيبيديا لديها شرح جيد لذلك:

" ...فقط بعد إنشاء مليار UUID كل ثانية على مدار المائة عام القادمة، سيكون احتمال إنشاء نسخة مكررة واحدة فقط حوالي 50%."

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

أول 4 بتات هي نوع الإصدار و2 بت للمتغير بحيث تحصل على 122 بت عشوائيًا.لذلك إذا كنت يريد يمكنك اقتطاعها من النهاية لتقليل حجم UUID.لا يُنصح بذلك ولكن لا يزال لديك قدر كبير من العشوائية، وهو ما يكفي لتسجيلاتك التي يبلغ عددها 500 ألف بسهولة.

حل قصير وسهل، ولكنه يستخدم الأحرف الصغيرة والأرقام فقط:

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

يبلغ الحجم حوالي 12 رقمًا للقاعدة 36 ولا يمكن تحسينه بهذه الطريقة.بالطبع يمكنك إلحاق حالات متعددة.

البديل في Java 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();
}
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;
}

يعد استخدام UUID غير آمن، لأن أجزاء من 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.لنفترض الحالة البسيطة لسلسلة عشوائية بطول 1، أي حرف عشوائي واحد.للحصول على حرف عشوائي يحتوي على جميع الأرقام من 0 إلى 9 والأحرف من a إلى z، سنحتاج إلى رقم عشوائي بين 0 و35 للحصول على واحد من كل حرف. BigInteger يوفر مُنشئًا لإنشاء رقم عشوائي، موزع بشكل موحد على النطاق 0 to (2^numBits - 1).لسوء الحظ، 35 ليس رقمًا يمكن استلامه بواسطة 2^numBits - 1.لذلك لدينا خياران:إما الذهاب مع 2^5-1=31 أو 2^6-1=63.لو اخترنا 2^6 سنحصل على الكثير من الأرقام "غير الضرورية"/"الأطول".لذلك 2^5 هو الخيار الأفضل، حتى لو فقدنا 4 أحرف (w-z).لإنشاء سلسلة ذات طول معين، يمكننا ببساطة استخدام ملف 2^(length*numBits)-1 رقم.المشكلة الأخيرة، إذا أردنا سلسلة بطول معين، فيمكن أن يولد العشوائي رقمًا صغيرًا، لذلك لم يتم استيفاء الطول، لذلك يتعين علينا ربط السلسلة بالطول المطلوب قبل الأصفار.

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

إذن ما يفعله هذا هو مجرد إضافة كلمة المرور إلى السلسلة و ...نعم يعمل بشكل جيد التحقق من ذلك ...بسيط جدا.لقد كتبت ذلك

لقد وجدت هذا الحل الذي يقوم بإنشاء سلسلة مشفرة عشوائية سداسية عشرية.يبدو أن اختبار الوحدة المقدمة يتوافق مع حالة الاستخدام الأساسية الخاصة بي.على الرغم من أنها أكثر تعقيدًا قليلاً من بعض الإجابات الأخرى المقدمة.

/**
 * 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);
        }
    }
}
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;
    }
}
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);
        }
    }
}
  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();
    }

لا يعجبك حقًا أي من هذه الإجابات فيما يتعلق بالحل "البسيط": S

سأختار بسيطًا ؛) وجافا نقية وبطانة واحدة (يعتمد الإنتروبيا على طول السلسلة العشوائية ومجموعة الأحرف المحددة):

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("-", "")

امل ان يساعد.

لقد ذكرت كلمة "بسيط"، ولكن في حالة بحث أي شخص آخر عن شيء يلبي متطلبات الأمان الأكثر صرامة، فقد ترغب في إلقاء نظرة على com.jpwgen.تم تصميم JPWGEN على غرار com.pwgen في Unix، وهو قابل للتكوين للغاية.

هنا هو حل سكالا:

(for (i <- 0 until rnd.nextInt(64)) yield { 
  ('0' + rnd.nextInt(64)).asInstanceOf[Char] 
}) mkString("")

يمكنك استخدام فئة UUID مع رسالتها getLeastSignificantBits() للحصول على 64 بت من البيانات العشوائية، ثم تحويلها إلى رقم 36 (أي 36 بت).سلسلة تتكون من 0-9، A-Z):

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

ينتج عن هذا سلسلة يصل طولها إلى 13 حرفًا.نحن نستخدم Math.abs() للتأكد من عدم وجود علامة ناقص تتسلل.

يمكنك استخدام الكود التالي، إذا كانت كلمة المرور الخاصة بك إلزامية تحتوي على أرقام أبجدية وأحرف خاصة:

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

}

هنا هو رمز سطر واحد بواسطة العدادUtil

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

باستخدام مكتبة اباتشي يمكن القيام بذلك في سطر واحد

import org.apache.commons.lang.RandomStringUtils;
RandomStringUtils.randomAlphanumeric(64);

هنا وثيقة http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/RandomStringUtils.html

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

أعتقد أن هذا هو الحل الأصغر هنا، أو ما يقرب من واحد من أصغر الحلول:

 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 ثواني.

public static String getRandomString(int length) 
{
   String randomStr = UUID.randomUUID().toString();
   while(randomStr.length() < length) {
       randomStr += UUID.randomUUID().toString();
   }
   return randomStr.substring(0, length);
}

ربما هذا مفيد

package password.generater;

import java.util.Random;

/**
 *
 * @author dell
 */
public class PasswordGenerater {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        int length= 11;
        System.out.println(generatePswd(length));

        // TODO code application logic here
    }
    static char[] generatePswd(int len){
        System.out.println("Your Password ");
        String charsCaps="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
        String Chars="abcdefghijklmnopqrstuvwxyz";
        String nums="0123456789";
        String symbols="!@#$%^&*()_+-=.,/';:?><~*/-+";
        String passSymbols=charsCaps + Chars + nums +symbols;
        Random rnd=new Random();
        char[] password=new char[len];

        for(int i=0; i<len;i++){
            password[i]=passSymbols.charAt(rnd.nextInt(passSymbols.length()));
        }
      return password;

    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top