[解決済み] 英数字のランダムな文字列を生成する方法
質問
を探していたのですが
シンプル
擬似的にランダムな英数字の文字列を生成するためのJavaアルゴリズム。 私の状況下では、これはセッション/キー識別子として使用され、quot;likely" で一意となります。
500K+
を生成します(私のニーズでは、これ以上高度なものは必要ありません)。
理想を言えば、一意性の必要性に応じて長さを指定できるようにしたいですね。例えば、長さ12の生成文字列は次のようになります。
"AEYGF7K0DM1X"
.
解決方法は?
アルゴリズム
ランダムな文字列を生成するには、許容される記号のセットからランダムに選んだ文字を、目的の長さになるまで連結する。
実装
以下は、ランダムな識別子を生成するための、非常にシンプルで柔軟なコードです。 以下の情報をお読みください。 は、重要なアプリケーションノートです。
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に含まれていたり、手で再入力されたりすると、エンコーディングの問題が発生する可能性があります。
セッション識別子のランダム性(エントロピー)の基礎となるソースは、暗号用に設計された乱数発生器から得る必要があります。しかし、これらの生成器の初期化には計算コストがかかったり、時間がかかったりすることがあるので、可能な限り再利用するように努力する必要があります。
オブジェクト識別子としての利用
すべての用途でセキュリティが必要なわけではありません。ランダム割り当ては、複数のエンティティが調整やパーティショニングを行わずに共有スペースに識別子を生成する効率的な方法です。特にクラスタや分散環境では、調整に時間がかかることがあります。また、空間を分割すると、エンティティが小さすぎたり大きすぎたりする共有になってしまうという問題が発生します。
予測できないようにする対策をとらずに生成された識別子は、多くのWebアプリケーションで起こるように、攻撃者が閲覧・操作できる可能性がある場合、別の手段で保護する必要があります。攻撃者がアクセス許可なしに識別子を推測できるようなオブジェクトを保護するために、別の認可システムを用意すべきです。
また、識別子の総数を想定して、衝突が起こりにくい十分な長さの識別子を使用するよう注意しなければならない。これは「誕生日のパラドックス」と呼ばれています。 衝突の確率を表す。 p であり、約n 2 /(2q x ), ここで n は実際に生成された識別子の数である。 q はアルファベット中の異なる記号の数であり x は識別子の長さです。これは2などの非常に小さな数であるべきです。 -50 またはそれ以下である。
これを計算すると、500k個の15文字識別子の間で衝突する確率は、約2 -52 これは、宇宙線などによる未検出のエラーよりも低い可能性でしょう。
UUIDとの比較
その仕様によると UUID は予測不可能なように設計されておらず はいけません。 をセッション識別子として使用します。
UUIDの標準的なフォーマットは、多くのスペースを必要とします。36文字で122ビットのエントロピーしかありません。(ランダムなUUIDのすべてのビットがランダムに選択されるわけではありません。)ランダムに選択された英数字の文字列は、わずか21文字でより多くのエントロピーをパックしています。
UUIDは柔軟性がなく、標準的な構造とレイアウトを持っています。これはUUIDの長所でもあり、短所でもあります。外部と共同作業をする場合、UUIDが提供する標準化は役に立つかもしれません。純粋に内部で使用する場合は、非効率的です。
関連
-
Java Exceptionが発生しました エラー解決
-
Eclipse起動エラー:javaは起動したが、終了コード=1を返した(ネット上の様々な落とし穴)
-
[解決済み] JavaScriptで文字列が部分文字列を含むかどうかを確認する方法は?
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] JavaでInputStreamを読み込んでStringに変換するにはどうすればよいですか?
-
[解決済み] JavaでStringをintに変換するにはどうしたらいいですか?
-
[解決済み] JavaScriptでランダムな文字列/文字を生成する
-
[解決済み] 乱数(int)を生成する方法を教えてください。
-
[解決済み] JavaScriptで2つの数値の間の乱数を生成する
-
[解決済み】JavaScriptで文字列の出現箇所をすべて置換する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
エラーが報告されました。リソースの読み込みに失敗しました:サーバーは500(内部サーバーエラー)のステータスで応答しました。
-
Java Exceptionが発生しました エラー解決
-
IllegalArgumentException この例外を解決する方法
-
javaの模造品QQ WeChatのチャットルーム
-
スキャナは、タイプに解決することはできません最もルーキー初心者の質問
-
コンストラクタの呼び出しは、コンストラクタのエラー理解の最初のステートメントである必要があります。
-
this()の呼び出しはコンストラクタ本体の最初の文でなければならない 例外解決と原因分析
-
spring-boot 401 このリソースにアクセスするには完全な認証が必要です エラー解決
-
起動時にEclipseエラーが発生しました。起動中に内部エラーが発生しました。java.lang.NullPoin: "Javaツーリングの初期化 "中に内部エラーが発生しました。
-
[解決済み] JavaでA-Zと0-9のランダムな文字列を作成する【重複