質問

私はずっと探していました 単純 擬似ランダムな英数字文字列を生成する Java アルゴリズム。私の状況では、それは「おそらく」一意になる一意のセッション/キー識別子として使用されます。 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);

セッション識別子として使用する

一意である可能性が高いセッション ID を生成するだけでは不十分です。あるいは、単純なカウンターを使用することもできます。攻撃者は、予測可能な識別子が使用されるとセッションをハイジャックします。

長さと安全性の間には緊張感があります。識別子が短いほど、可能性が少なくなるため、推測が容易になります。ただし、識別子が長くなると、より多くのストレージと帯域幅が消費されます。シンボルのセットが大きいほど役に立ちますが、識別子が URL に含まれている場合や手動で再入力されている場合は、エンコードの問題が発生する可能性があります。

セッション識別子の根本的なランダム性またはエントロピーのソースは、暗号化用に設計された乱数ジェネレーターから得られる必要があります。ただし、これらのジェネレーターの初期化は計算コストが高かったり、時間がかかったりする場合があるため、可能な場合は再利用するように努める必要があります。

オブジェクト識別子として使用する

すべてのアプリケーションにセキュリティが必要なわけではありません。ランダムな割り当ては、複数のエンティティが調整や分割を行わずに共有スペースで識別子を生成する効率的な方法となります。特にクラスター環境または分散環境では、調整が遅くなる可能性があり、エンティティの共有が小さすぎるか大きすぎる場合、スペースを分割すると問題が発生します。

予測不可能にするための措置を講じずに生成された識別子は、ほとんどの Web アプリケーションで発生するように、攻撃者が識別子を表示および操作できる可能性がある場合には、他の手段で保護する必要があります。アクセス許可なしに攻撃者によって識別子が推測される可能性のあるオブジェクトを保護する別の認証システムが必要です。

また、予想される識別子の合計数を考慮して、衝突が起こりにくくなるのに十分な長さの識別子を使用するように注意する必要があります。これを「誕生日のパラドックス」といいます。 衝突の確率、 p, 、はおよそ n2/(2qバツ)、 どこ n 実際に生成される識別子の数です。 q はアルファベット内の個別の記号の数であり、 バツ 識別子の長さです。これは 2 のような非常に小さな数値である必要があります‑50 以下。

これを計算すると、500,000 個の 15 文字の識別子間の衝突の可能性は約 2 であることがわかります。‑52, 、これはおそらく宇宙線などによる未検出のエラーよりも可能性が低いでしょう。

UUIDとの比較

仕様によれば、UUID は予測不可能になるように設計されておらず、 いけない セッション識別子として使用されます。

標準形式の UUID は多くのスペースを必要とします。36 文字で 122 ビットのエントロピーのみ。(「ランダム」UU​​ID のすべてのビットがランダムに選択されるわけではありません。) ランダムに選択された英数字文字列は、わずか 21 文字により多くのエントロピーを詰め込みます。

UUID は柔軟性がありません。標準化された構造とレイアウトを持っています。これは彼らの主な美徳であると同時に主な弱点でもあります。外部パーティと協力する場合、UUID によって提供される標準化が役立つ場合があります。純粋に内部使用の場合、非効率的になる可能性があります。

他のヒント

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

commons-lang 3.6以降、 RandomStringUtils は廃止されました。

一行で:

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

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

これには Apache ライブラリを使用できます。 ランダム文字列ユーティリティ

RandomStringUtils.randomAlphanumeric(20).toUpperCase();

これは、外部ライブラリを使用せずに簡単に実現できます。

1.暗号化擬似ランダムデータ生成

まず、暗号化 PRNG が必要です。Javaには SecureRandom そのため、通常はマシン上で最適なエントロピー ソースが使用されます (例: /dev/random) . 詳細はこちらをご覧ください。

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

注記: SecureRandom これは、Java でランダム バイトを生成する最も遅い方法ですが、最も安全な方法です。ただし、1 秒あたり数百万のトークンを生成する必要がない限り、通常はアプリケーションに実際の影響を与えないため、ここではパフォーマンスを考慮しないことをお勧めします。

2.可能な値の必須スペース

次に、トークンが「どの程度ユニークであるか」を決定する必要があります。エントロピーを考慮する唯一のポイントは、システムがブルート フォース攻撃に対抗できることを確認することです。考えられる値の空間は、攻撃者がばかばかしい時間内にごくわずかな割合の値しか試行できないほど大きくなければなりません。1. 。ランダムなどの一意の識別子 UUID 122ビットのエントロピーを持っています(つまり、2^122 = 5.3x10^36) - 衝突の確率は「*(...) 10 億分の 1 の確率で重複するためには、103 兆個のバージョン 4 UUID を生成する必要があります」2". 128 ビットは 16 バイトに正確に収まるため、128 ビットを選択します。 そして次のように見られます 非常に十分な 基本的にすべてのユースケース(ただし最も極端なユースケース)に対して一意であるため、重複について考える必要がありません。これは、エントロピーの簡単な分析を含む、エントロピーの簡単な比較表です。 誕生日の問題.

comparison of token sizes

単純な要件の場合は 8 バイトまたは 12 バイトの長さで十分かもしれませんが、16 バイトであれば「安全側」になります。

基本的にはそれだけです。最後に、印刷可能なテキスト (つまり、 String).

3.バイナリからテキストへのエンコーディング

一般的なエンコーディングには次のものがあります。

  • Base64 すべての文字は 6 ビットをエンコードし、33% のオーバーヘッドが発生します。幸いなことに、標準実装が存在します。 Java 8+ そして アンドロイド. 。古い Java では、次のいずれかを使用できます。 多数のサードパーティライブラリ. 。トークンを URL 安全にしたい場合は、 URLセーフ RFC4648 のバージョン (通常、ほとんどの実装でサポートされています)。パディングを使用して 16 バイトをエンコードする例: XfJhfv3C0P6ag7y9VQxSbw==

  • Base32 すべての文字は 5 ビットをエンコードし、40% のオーバーヘッドが発生します。これは使用します A-Z そして 2-7 これにより、大文字と小文字を区別しない英数字を使用しながら、適度にスペース効率を高めることができます。ありません JDK での標準実装. 。パディングなしで 16 バイトをエンコードする例: WUPIL5DQTZGMF4D3NX5L7LNFOY

  • Base16 (16 進数) すべての文字は、バイトごとに 2 文字を必要とする 4 ビットをエンコードします (つまり、16 バイトで長さ 32 の文字列が作成されます)。したがって、16 進数はスペース効率が低くなります。 Base32 ただし、使用するのは URL のみであるため、ほとんどの場合安全に使用できます。 0-9 そして AF. 。16バイトをエンコードする例: 4fa3dd0f57cb3bf331441ed285b27735. ここで 16 進数への変換に関する SO の議論を参照してください。

追加のエンコーディング Base85 そしてエキゾチックな Base122 スペース効率が良い/悪いで存在します。独自のエンコーディングを作成することもできます(基本的にこのスレッドのほとんどの回答はそうします)が、非常に具体的な要件がない場合は、作成しないことをお勧めします。見る 他のエンコーディング スキームについては、Wikipedia の記事を参照してください。

4.概要と例

  • 使用 SecureRandom
  • 少なくとも 16 バイト (2^128) の可能な値を使用してください
  • 要件に従ってエンコードします (通常は hex または base32 英数字にする必要がある場合)

やめてください

  • ...自家製エンコーディングを使用します。 一度に文字を作成する奇妙な for ループの代わりに、使用している標準エンコーディングを他の人が確認できれば、メンテナンス性と読みやすさが向上します。
  • ...UUIDを使用します: ランダム性については何の保証もありません。6ビットのエントロピーを無駄にしており、冗長な文字列表現を持っています

例:16 進トークン ジェネレーター

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

例:Java CLI ツール

すぐに使える cli ツールが必要な場合は、dice を使用できます。 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

Java では次のようになります。

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

簡単。

この利点は、UUID が長くて優れており、衝突がほぼ不可能であることが保証されていることです。

Wikipedia にはそれについての詳しい説明があります。

「 ...今後 100 年間、毎秒 10 億の UUID が生成された後のみ、重複が 1 つだけ作成される確率は約 50% になります。」

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

最初の 4 ビットはバージョン タイプ、2 ビットはバリアントであるため、122 ビットのランダムが得られます。それで、あなたが 欲しい 末尾から切り詰めて UUID のサイズを減らすことができます。推奨されませんが、それでもランダム性が十分にあるので、500,000 レコードを簡単に作成するには十分です。

短くて簡単な解決策ですが、小文字と数字のみを使用します。

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

サイズは 36 進数で約 12 桁であり、これ以上改善することはできません。もちろん、複数のインスタンスを追加することもできます。

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 のランダムな文字列、つまり 1 つのランダムな文字の単純なケースを想定してみましょう。0 ~ 9 のすべての数字と a ~ z の文字を含むランダムな文字を取得するには、各文字を 1 つ取得するために 0 ~ 35 の乱数が必要です。 BigInteger 範囲全体に均一に分布する乱数を生成するコンストラクターを提供します。 0 to (2^numBits - 1). 。残念ながら、35 は 2^numBits - 1 で受信できる数ではありません。したがって、2 つの選択肢があります。どちらかと一緒に行きましょう 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);
    }
}

つまり、これは文字列にパスワードを追加するだけです...はい、うまくいきます、チェックしてください...とてもシンプルです。私はそれを書きました

ランダムな 16 進数でエンコードされた文字列を生成するこのソリューションを見つけました。提供された単体テストは、私の主な使用例に耐えられるようです。ただし、提供されている他の回答よりも少し複雑です。

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

私は単純な ;)、純粋な Java、ワンライナーを使用します (エントロピーはランダムな文字列の長さと指定された文字セットに基づいています)。

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

それが役立つことを願っています。

「シンプル」とおっしゃっていますが、より厳格なセキュリティ要件を満たすものを探している人がいる場合に備えて、以下を見てみるのもいいかもしれません。 jpwgen. 。jpwgen のモデルとなっている パワージェン Unix では非常に構成可能です。

これが Scala ソリューションです。

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

UUID クラスを getLeastSignificantBits() メッセージとともに使用して、64 ビットのランダム データを取得し、それを基数 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();

}

これはによる1行のコードです そろばん利用

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

Apacheライブラリを使用すると1行で実行できます

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

これがここでの最小の解決策、またはほぼ最小の解決策の 1 つであると思います。

 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