答えて
UUIDは、定義ごとに16バイトの数であるので、それが不可能です。もちろん、8文字の長い一意の文字列を生成することができます(他の回答を参照)。
IDの一部に固定バイトが含まれる可能性があるため、長いUUIDを生成して部分文字列を入力することにも注意してください(MAC、DCE、MD5 UUIDの場合など)。
how about timestamp –
@annapoorani:タイムスタンプがマルチスレッドアクセスのために衝突する – peaceUser
私はそれは可能だとは思わないが、良い回避策があります。
- カットあなたのUUID使用して、サブストリング()
- 利用コード
new Random(System.currentTimeMillis()).nextInt(99999999);
の終わりには、これは長い8つの文字にランダムなIDを生成します。 は、英数字のIDを生成する:
char[] chars = "abcdefghijklmnopqrstuvwxyzABSDEFGHIJKLMNOPQRSTUVWXYZ1234567890".toCharArray(); Random r = new Random(System.currentTimeMillis()); char[] id = new char[8]; for (int i = 0; i < 8; i++) { id[i] = chars[r.nextInt(chars.length)]; } return new String(id);
残念ながら、これらのアプローチはすべて、あなたが望むよりも早くリピート(つまり固有でないID)を与える可能性があります。 –
空のコンストラクタを使用するよりも現在の日付をランダムに生成するのがより少ないですか? – for3st
最初:java UUID.randomUUIDまたは.net GUIDによって生成された一意のIDであっても100%ユニークではありません。特にUUID.randomUUIDは128ビット(安全な)ランダム値の「唯一の」ものです。したがって、64ビット、32ビット、16ビット(または1ビット)に縮小すると、一意性が低下します。
少なくともリスクに基づく決定、あなたのuuidがどれぐらい長くなければならないか、ということです。
2番目:「8文字のみ」と言えば、通常の8文字の印刷可能文字列を意味します。
長さ8の印刷可能な文字で一意の文字列を使用する場合は、base64エンコーディングを使用できます。 6バイトのランダム配列を作成
SecureRandom rand;
// ...
byte[] randomBytes = new byte[16];
rand.nextBytes(randomBytes);
: - (しかし、多分それはあなたのアプリケーションのためokです非常にユニークなことができない)ので、方法は簡単です
を使用すると、合計で48ビットを取得するのでこれは、文字ごとに6ビットを意味し、
BTW: "uuid"を作成してランダムに作成する方が良い場合は、アプリケーションによって異なります。 (UUIDを1秒に1回だけ作成する場合は、タイムスタンプを追加することをお勧めします) (ちなみに、2つのランダムな値を組み合わせると、結果は常に少なくとも両者のほとんどはランダム)。
これはどうですか。実際には、このコードは最大13文字を返しますが、UUIDよりも短くなります。
import java.nio.ByteBuffer;
import java.util.UUID;
/**
* Generate short UUID (13 characters)
*
* @return short UUID
*/
public static String shortUUID() {
UUID uuid = UUID.randomUUID();
long l = ByteBuffer.wrap(uuid.toString().getBytes()).getLong();
return Long.toString(l, Character.MAX_RADIX);
}
'getLong()'はバッファの最初の8バイトだけを読み取っていることを知っています。 UUIDには少なくとも36バイトが必要です。私に何かが見当たらないのは、これは決してうまくいかないからです。 –
最初の8バイトはUUIDの最上位ビットです。 [この回答](http://stackoverflow.com/a/325457/851344)によると、下位ビットはよりランダムです。だから 'Long.toString(uuid.getLessSignificantBits()、Character.MAX_RADIX)'が優れています。 – DouO
あなたはRandomStringUtils
class from apache.commonsを試すことができます@Cephalopodはそれができません述べていますが、22文字
public static String encodeUUIDBase64(UUID uuid) {
ByteBuffer bb = ByteBuffer.wrap(new byte[16]);
bb.putLong(uuid.getMostSignificantBits());
bb.putLong(uuid.getLeastSignificantBits());
return StringUtils.trimTrailingCharacter(BaseEncoding.base64Url().encode(bb.array()), '=');
}
にUUIDを短縮することができたよう:
import org.apache.commons.lang3.RandomStringUtils;
final int SHORT_ID_LENGTH = 8;
// all possible unicode characters
String shortId = RandomStringUtils.random(SHORT_UID_LENGTH);
心に留めておいてください、それは、URLでも人間にも優しいものではない可能性のあるすべての文字を含むことになる。
だから、あまりにも他の方法をチェックアウト:
// HEX: 0-9, a-f. For example: 6587fddb, c0f182c1
shortId = RandomStringUtils.random(8, "abcdef");
// a-z, A-Z. For example: eRkgbzeF, MFcWSksx
shortId = RandomStringUtils.randomAlphabetic(8);
// 0-9. For example: 76091014, 03771122
shortId = RandomStringUtils.randomNumeric(8);
// a-z, A-Z, 0-9. For example: WRMcpIk7, s57JwCVA
shortId = RandomStringUtils.randomAlphanumeric(8);
他は小さいIDを持つIDの衝突の確率が大きくなる可能性が言ったように。あなたのケースにどのようにbirthday problemが適用されるかを確認してください。あなたはthis answerで近似を計算する方法を説明しています。
'org.apache.commons.lang3.RandomStringUtils'は廃止予定ですので、https://commons.apache.org/proper/commons-text/で' org.apache.commons.text.RandomStringGenerator'を使うほうがよいでしょう。 – BrunoJCM
'RandomStringGenerator'の新しい答えが追加されました。全く異なるコードです。 – BrunoJCM
将来の視聴者のためのちょっとした一言、偶然性は一意性を保証するものではありません。ランダムジェネレータはランダム性を保証します。繰り返し値を持つ有効な乱数のセットを生成することができます。 –
実際にタイムスタンプベースのより短い一意の識別子が必要なので、以下のプログラムを試してみてください。
nanosecond + (endians.length * endians.length)
の組み合わせで推測できます。
public class TimStampShorterUUID {
private static final Character [] endians =
{'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',
'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'
};
private static ThreadLocal<Character> threadLocal = new ThreadLocal<Character>();
private static AtomicLong iterator = new AtomicLong(-1);
public static String generateShorterTxnId() {
// Keep this as secure random when we want more secure, in distributed systems
int firstLetter = ThreadLocalRandom.current().nextInt(0, (endians.length));
//Sometimes your randomness and timestamp will be same value,
//when multiple threads are trying at the same nano second
//time hence to differentiate it, utilize the threads requesting
//for this value, the possible unique thread numbers == endians.length
Character secondLetter = threadLocal.get();
if (secondLetter == null) {
synchronized (threadLocal) {
if (secondLetter == null) {
threadLocal.set(endians[(int) (iterator.incrementAndGet() % endians.length)]);
}
}
secondLetter = threadLocal.get();
}
return "" + endians[firstLetter] + secondLetter + System.nanoTime();
}
public static void main(String[] args) {
Map<String, String> uniqueKeysTestMap = new ConcurrentHashMap<>();
Thread t1 = new Thread() {
@Override
public void run() {
while(true) {
String time = generateShorterTxnId();
String result = uniqueKeysTestMap.put(time, "");
if(result != null) {
System.out.println("failed! - " + time);
}
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
while(true) {
String time = generateShorterTxnId();
String result = uniqueKeysTestMap.put(time, "");
if(result != null) {
System.out.println("failed! - " + time);
}
}
}
};
Thread t3 = new Thread() {
@Override
public void run() {
while(true) {
String time = generateShorterTxnId();
String result = uniqueKeysTestMap.put(time, "");
if(result != null) {
System.out.println("failed! - " + time);
}
}
}
};
Thread t4 = new Thread() {
@Override
public void run() {
while(true) {
String time = generateShorterTxnId();
String result = uniqueKeysTestMap.put(time, "");
if(result != null) {
System.out.println("failed! - " + time);
}
}
}
};
Thread t5 = new Thread() {
@Override
public void run() {
while(true) {
String time = generateShorterTxnId();
String result = uniqueKeysTestMap.put(time, "");
if(result != null) {
System.out.println("failed! - " + time);
}
}
}
};
Thread t6 = new Thread() {
@Override
public void run() {
while(true) {
String time = generateShorterTxnId();
String result = uniqueKeysTestMap.put(time, "");
if(result != null) {
System.out.println("failed! - " + time);
}
}
}
};
Thread t7 = new Thread() {
@Override
public void run() {
while(true) {
String time = generateShorterTxnId();
String result = uniqueKeysTestMap.put(time, "");
if(result != null) {
System.out.println("failed! - " + time);
}
}
}
};
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
t7.start();
}
}
UPDATE:このコードは、単一のJVM上で動作しますが、我々は、分散JVM上で考えなければならない、それゆえ私は2つの解決策DBと1とDBのない別のものを考えています。 DB
会社名(短縮名3文字)---- ---- RANDOM_NUMBERキー特定Redisのカウンターで
(3文字)-------------- ----------------------------------(2文字)------------ ----(11 CHAR)
DB
せずIPADDRESS ---- ---- THREAD_NUMBER INCR_NUMBER ----エポックミリ秒
(5文字)を--------- --------(2char)-----------------------(2char)------------ -----(6文字)
は、コーディングが完了すると更新されます。
これは私がアントンプリンの回答に基づいて、固有のエラーコードを生成するために、ここで使用している同様の方法であるが、代わりに非推奨org.apache.commons.lang3.RandomStringUtils
のorg.apache.commons.text.RandomStringGenerator
頼る:まだ適用
@Singleton
@Component
public class ErrorCodeGenerator implements Supplier<String> {
private RandomStringGenerator errorCodeGenerator;
public ErrorCodeGenerator() {
errorCodeGenerator = new RandomStringGenerator.Builder()
.withinRange('0', 'z')
.filteredBy(t -> t >= '0' && t <= '9', t -> t >= 'A' && t <= 'Z', t -> t >= 'a' && t <= 'z')
.build();
}
@Override
public String get() {
return errorCodeGenerator.generate(8);
}
}
衝突に関する全てのアドバイスを、それらに注意してください。
- 1. ARCを有効にしてUUID文字列を生成する
- 2. 生成UUID
- 3. Laravel UUIDの生成
- 4. UTF-8以外の文字セットを生成するには
- 5. DynamoDBのUUIDを自動生成する
- 6. 128BitのUUIDを文字列で作成する
- 7. UUIDの最大文字長
- 8. cutdown uuidさらに短い文字列を作成する
- 9. Ubuntu OSでUUIDを生成する
- 10. UUIDを30文字未満にする
- 11. EFSのUUID作成トークンを生成
- 12. Javaで8バイトの数字を生成
- 13. .netでUTF-8文字セット内のすべての文字を生成する方法
- 14. UTF-8でXMLファイルを生成する際に文字エンコーディングの問題
- 15. アプリケーションUUIDを生成しますか?
- 16. MySQL WorkbenchプライマリキーのUUIDを自動生成
- 17. UTF-8:文字コード(文字コード)で文字(文字列)を作成
- 18. UUIDをショートコードにすることは安全ですか? (最初の8文字のみを使用します)
- 19. 文字列のパワーセットを生成する
- 20. シーケンスの文字数を生成する
- 21. Scalacheckは常にList [UUID]の任意のUUIDを生成します
- 22. SpakrSQL UUIDで新しい列を生成
- 23. Freemarker:便利にUUIDを生成
- 24. アンドロイド(UUID)でユニークなIDを生成
- 25. JavaでUUID Type 2を生成
- 26. springのanootationsを使ってUUIDを生成する方法
- 27. ランダムな文字を生成する
- 28. メモリマップを生成する文字列
- 29. ランダムなASCII文字を生成する
- 30. ランダムな文字列を生成する
しかし、実際にはそれほど単純ではない可能性は低いです。なぜ? – delnan
@delnan、組み込み環境で使用するには? –