Skip to content

Commit fe2c37c

Browse files
DaveCTurnercbuescher
authored andcommitted
Add constants for UUID lengths (elastic#112353)
Our UUID strings have fixed lengths (depending on the type of UUID). Sometimes we might want code to rely on knowing these lengths rather than doing some other string manipulations to look for a boundary. This commit exposes constants for these things.
1 parent 3ae5510 commit fe2c37c

File tree

5 files changed

+57
-12
lines changed

5 files changed

+57
-12
lines changed

server/src/main/java/org/elasticsearch/common/RandomBasedUUIDGenerator.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ public static String getBase64UUID(Random random) {
5656
return Base64.getUrlEncoder().withoutPadding().encodeToString(getUUIDBytes(random));
5757
}
5858

59+
static final int SIZE_IN_BYTES = 16;
60+
5961
private static byte[] getUUIDBytes(Random random) {
60-
final byte[] randomBytes = new byte[16];
62+
final byte[] randomBytes = new byte[SIZE_IN_BYTES];
6163
random.nextBytes(randomBytes);
6264
/* Set the version to version 4 (see http://www.ietf.org/rfc/rfc4122.txt)
6365
* The randomly or pseudo-randomly generated version.

server/src/main/java/org/elasticsearch/common/TimeBasedUUIDGenerator.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ protected byte[] macAddress() {
4747
return SECURE_MUNGED_ADDRESS;
4848
}
4949

50+
static final int SIZE_IN_BYTES = 15;
51+
5052
@Override
5153
public String getBase64UUID() {
5254
final int sequenceId = sequenceNumber.incrementAndGet() & 0xffffff;
@@ -61,7 +63,7 @@ public String getBase64UUID() {
6163
sequenceId == 0 ? (lastTimestamp, currentTimeMillis) -> Math.max(lastTimestamp, currentTimeMillis) + 1 : Math::max
6264
);
6365

64-
final byte[] uuidBytes = new byte[15];
66+
final byte[] uuidBytes = new byte[SIZE_IN_BYTES];
6567
int i = 0;
6668

6769
// We have auto-generated ids, which are usually used for append-only workloads.

server/src/main/java/org/elasticsearch/common/UUIDs.java

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,50 @@ public class UUIDs {
1717
private static final RandomBasedUUIDGenerator RANDOM_UUID_GENERATOR = new RandomBasedUUIDGenerator();
1818
private static final UUIDGenerator TIME_UUID_GENERATOR = new TimeBasedUUIDGenerator();
1919

20-
/** Generates a time-based UUID (similar to Flake IDs), which is preferred when generating an ID to be indexed into a Lucene index as
21-
* primary key. The id is opaque and the implementation is free to change at any time! */
20+
/**
21+
* The length of a UUID string generated by {@link #base64UUID}.
22+
*/
23+
// A 15-byte time-based UUID is base64-encoded as 5 3-byte chunks (each becoming 4 chars after encoding).
24+
public static final int TIME_BASED_UUID_STRING_LENGTH = 20;
25+
26+
/**
27+
* Generates a time-based UUID (similar to Flake IDs), which is preferred when generating an ID to be indexed into a Lucene index as
28+
* primary key. The id is opaque and the implementation is free to change at any time!
29+
* The resulting string has length {@link #TIME_BASED_UUID_STRING_LENGTH}.
30+
*/
2231
public static String base64UUID() {
2332
return TIME_UUID_GENERATOR.getBase64UUID();
2433
}
2534

26-
/** Returns a Base64 encoded version of a Version 4.0 compatible UUID as defined here: http://www.ietf.org/rfc/rfc4122.txt, using the
27-
* provided {@code Random} instance */
35+
/**
36+
* The length of a UUID string generated by {@link #randomBase64UUID} and {@link #randomBase64UUIDSecureString}.
37+
*/
38+
// A 16-byte v4 UUID is base64-encoded as 5 3-byte chunks (each becoming 4 chars after encoding) plus another byte (becomes 2 chars).
39+
public static final int RANDOM_BASED_UUID_STRING_LENGTH = 22;
40+
41+
/**
42+
* Returns a Base64 encoded string representing a <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC4122 version 4 UUID</a>, using the
43+
* provided {@code Random} instance.
44+
* The resulting string has length {@link #RANDOM_BASED_UUID_STRING_LENGTH}.
45+
*/
2846
public static String randomBase64UUID(Random random) {
2947
return RandomBasedUUIDGenerator.getBase64UUID(random);
3048
}
3149

32-
/** Returns a Base64 encoded version of a Version 4.0 compatible UUID as defined here: http://www.ietf.org/rfc/rfc4122.txt, using a
33-
* private {@code SecureRandom} instance */
50+
/**
51+
* Returns a Base64 encoded string representing a <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC4122 version 4 UUID</a>, using a
52+
* private {@code SecureRandom} instance.
53+
* The resulting string has length {@link #RANDOM_BASED_UUID_STRING_LENGTH}.
54+
*/
3455
public static String randomBase64UUID() {
3556
return RANDOM_UUID_GENERATOR.getBase64UUID();
3657
}
3758

38-
/** Returns a Base64 encoded {@link SecureString} of a Version 4.0 compatible UUID as defined here: http://www.ietf.org/rfc/rfc4122.txt,
39-
* using a private {@code SecureRandom} instance */
59+
/**
60+
* Returns a Base64 encoded {@link SecureString} representing a <a href="http://www.ietf.org/rfc/rfc4122.txt">RFC4122 version 4
61+
* UUID</a>, using a private {@code SecureRandom} instance.
62+
* The resulting string has length {@link #RANDOM_BASED_UUID_STRING_LENGTH}.
63+
*/
4064
public static SecureString randomBase64UUIDSecureString() {
4165
return RandomBasedUUIDGenerator.getBase64UUIDSecureString();
4266
}

server/src/test/java/org/elasticsearch/common/UUIDTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,20 @@ protected byte[] macAddress() {
176176
);
177177
return bytesPerDoc;
178178
}
179+
180+
public void testStringLength() {
181+
assertEquals(UUIDs.RANDOM_BASED_UUID_STRING_LENGTH, getUnpaddedBase64StringLength(RandomBasedUUIDGenerator.SIZE_IN_BYTES));
182+
assertEquals(UUIDs.RANDOM_BASED_UUID_STRING_LENGTH, UUIDs.randomBase64UUID().length());
183+
assertEquals(UUIDs.RANDOM_BASED_UUID_STRING_LENGTH, UUIDs.randomBase64UUID(random()).length());
184+
try (var secureString = UUIDs.randomBase64UUIDSecureString()) {
185+
assertEquals(UUIDs.RANDOM_BASED_UUID_STRING_LENGTH, secureString.toString().length());
186+
}
187+
188+
assertEquals(UUIDs.TIME_BASED_UUID_STRING_LENGTH, getUnpaddedBase64StringLength(TimeBasedUUIDGenerator.SIZE_IN_BYTES));
189+
assertEquals(UUIDs.TIME_BASED_UUID_STRING_LENGTH, UUIDs.base64UUID().length());
190+
}
191+
192+
private static int getUnpaddedBase64StringLength(int sizeInBytes) {
193+
return (int) Math.ceil(sizeInBytes * 4.0 / 3.0);
194+
}
179195
}

test/framework/src/main/java/org/elasticsearch/repositories/blobstore/RepositoryFileType.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
package org.elasticsearch.repositories.blobstore;
1010

1111
import org.elasticsearch.common.Strings;
12+
import org.elasticsearch.common.UUIDs;
1213

1314
import java.nio.file.Path;
1415
import java.util.regex.Pattern;
@@ -38,9 +39,9 @@ public enum RepositoryFileType {
3839
// decimal numbers
3940
.replace("NUM", "(0|[1-9][0-9]*)")
4041
// 15-byte UUIDS from TimeBasedUUIDGenerator
41-
.replace("SHORTUUID", "[0-9a-zA-Z_-]{20}")
42+
.replace("SHORTUUID", "[0-9a-zA-Z_-]{" + UUIDs.TIME_BASED_UUID_STRING_LENGTH + "}")
4243
// 16-byte UUIDs from RandomBasedUUIDGenerator
43-
.replace("UUID", "[0-9a-zA-Z_-]{22}")
44+
.replace("UUID", "[0-9a-zA-Z_-]{" + UUIDs.RANDOM_BASED_UUID_STRING_LENGTH + "}")
4445
+ ")$"
4546
);
4647
}

0 commit comments

Comments
 (0)