ユニークなバイトシーケンスを生成するための効率的なユーティリティが必要です。UUIDは良い候補ですが、そのUUID.randomUUID().toString()
ようなものを生成します44e128a5-ac7a-4c9a-be4c-224b6bf81b20
が、私はダッシュなしの文字列を好みます。
英数字のみ(ダッシュやその他の特殊記号なし)からランダムな文字列を生成する効率的な方法を探しています。
ユニークなバイトシーケンスを生成するための効率的なユーティリティが必要です。UUIDは良い候補ですが、そのUUID.randomUUID().toString()
ようなものを生成します44e128a5-ac7a-4c9a-be4c-224b6bf81b20
が、私はダッシュなしの文字列を好みます。
英数字のみ(ダッシュやその他の特殊記号なし)からランダムな文字列を生成する効率的な方法を探しています。
回答:
これはそれを行います:
public static void main(String[] args) {
final String uuid = UUID.randomUUID().toString().replace("-", "");
System.out.println("uuid = " + uuid);
}
このスレッドのURLで確認できるように、HTTPリクエストからダッシュを削除する必要はありません。ただし、データに依存せずに整形式のURLを準備する場合は、データの標準形式を変更する代わりに、URLEncoder.encode(String data、String encoding)を使用する必要があります。UUID文字列表現の場合、ダッシュは正常です。
http://stackoverflow.com/questions/3804591/efficient-method-to-generate-uuid-string-in-java-uuid-randomuuid-tostring-w?rq=1
結局、UUID.java実装に基づいて独自の何かを書くことになりました。私がUUIDを生成しているわけではないことに注意してください。代わりに、私が考えることができる最も効率的な方法でランダムな32バイトの16進文字列を生成します。
import java.security.SecureRandom;
import java.util.UUID;
public class RandomUtil {
// Maxim: Copied from UUID implementation :)
private static volatile SecureRandom numberGenerator = null;
private static final long MSB = 0x8000000000000000L;
public static String unique() {
SecureRandom ng = numberGenerator;
if (ng == null) {
numberGenerator = ng = new SecureRandom();
}
return Long.toHexString(MSB | ng.nextLong()) + Long.toHexString(MSB | ng.nextLong());
}
}
RandomUtil.unique()
動作することを確認するためにテストした入力の一部:
public static void main(String[] args) {
System.out.println(UUID.randomUUID().toString());
System.out.println(RandomUtil.unique());
System.out.println();
System.out.println(Long.toHexString(0x8000000000000000L |21));
System.out.println(Long.toBinaryString(0x8000000000000000L |21));
System.out.println(Long.toHexString(Long.MAX_VALUE + 1));
}
JUG(Java UUID Generator)を使用して一意のIDを生成しました。これはJVM全体で一意です。かなり使いやすいです。あなたの参照のためのコードはここにあります:
private static final SecureRandom secureRandom = new SecureRandom();
private static final UUIDGenerator generator = UUIDGenerator.getInstance();
public synchronized static String generateUniqueId() {
UUID uuid = generator.generateRandomBasedUUID(secureRandom);
return uuid.toString().replaceAll("-", "").toUpperCase();
}
ライブラリはhttps://github.com/cowtowncoder/java-uuid-generatorからダウンロードできます。
java.util.UUID
代替案があることを知っておくのは良いことです。
簡単な解決策は
UUID.randomUUID().toString().replace("-", "")
(既存のソリューションと同様に、String#replaceAll呼び出しを回避するだけです。ここでは正規表現の置換は不要であるため、技術的には正規表現で実装されていますが、String#replaceはより自然に感じられます。UUIDの生成が交換よりも費用がかかりますが、ランタイムに大きな違いはありません。)
UUIDクラスを使用すると、ほとんどのシナリオでおそらく十分高速ですが、後処理を必要としない一部の特殊な手書きのバリアントが高速であることが期待されます。とにかく、全体的な計算のボトルネックは通常、乱数ジェネレーターです。UUIDクラスの場合は、SecureRandomを使用します。
使用する乱数ジェネレーターも、アプリケーションに依存するトレードオフです。セキュリティが重要な場合は、SecureRandomが一般的に推奨されます。それ以外の場合は、ThreadLocalRandomが代わりになります(SecureRandomまたは古いRandomより高速ですが、暗号的に安全ではありません)。
多くの文字列がUUIDのアイデアを置き換えるのを見て、私は驚いています。これはどう:
UUID temp = UUID.randomUUID();
String uuidString = Long.toHexString(temp.getMostSignificantBits())
+ Long.toHexString(temp.getLeastSignificantBits());
これは、UUIDのtoString()全体が、解析および実行する必要がある正規表現や空の文字列での置換は言うまでもなく、すでにより高価であるため、これを行う高速な方法です。
String.format("0x%016x%016x", f.getMostSignificantBits(), f.getLeastSignificantBits())
replace
ます。
UUID toString()メソッドをコピーし、「-」を削除するために更新しました。他のソリューションよりもはるかに高速で簡単です
public String generateUUIDString(UUID uuid) {
return (digits(uuid.getMostSignificantBits() >> 32, 8) +
digits(uuid.getMostSignificantBits() >> 16, 4) +
digits(uuid.getMostSignificantBits(), 4) +
digits(uuid.getLeastSignificantBits() >> 48, 4) +
digits(uuid.getLeastSignificantBits(), 12));
}
/** Returns val represented by the specified number of hex digits. */
private String digits(long val, int digits) {
long hi = 1L << (digits * 4);
return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}
使用法:
generateUUIDString(UUID.randomUUID())
リフレクションを使用した別の実装
public String generateString(UUID uuid) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
if (uuid == null) {
return "";
}
Method digits = UUID.class.getDeclaredMethod("digits", long.class, int.class);
digits.setAccessible(true);
return ( (String) digits.invoke(uuid, uuid.getMostSignificantBits() >> 32, 8) +
digits.invoke(uuid, uuid.getMostSignificantBits() >> 16, 4) +
digits.invoke(uuid, uuid.getMostSignificantBits(), 4) +
digits.invoke(uuid, uuid.getLeastSignificantBits() >> 48, 4) +
digits.invoke(uuid, uuid.getLeastSignificantBits(), 12));
}
私はorg.apache.commons.codec.binary.Base64を使用して、UUIDを22文字の長さでUUIDと同じ一意性を持つURLセーフの一意の文字列に変換します。
コードをbase64文字列としてUUIDを格納するに投稿しました