All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.seeq.utilities.UUIDs Maven / Gradle / Ivy

The newest version!
package com.seeq.utilities;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.time.Clock;
import java.util.Arrays;
import java.util.Base64;
import java.util.UUID;
import java.util.regex.Pattern;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;

/**
 * Collection of methods for interacting with and generating UUIDs
 */
public class UUIDs {
    public static final Pattern ID_PATTERN = Pattern.compile("\\p{XDigit}{8}-(\\p{XDigit}{4}-){3}\\p{XDigit}{12}");
    private static final Generator GENERATOR = new Generator(Clock.systemUTC());

    /**
     * Generates a random base64 guid
     *
     * @return the random base64 guid
     */
    public static String randomBase64Guid() {
        UUID uuid = UUID.randomUUID();
        byte[] src = ByteBuffer.wrap(new byte[16])
                .putLong(uuid.getMostSignificantBits())
                .putLong(uuid.getLeastSignificantBits())
                .array();
        return Base64.getUrlEncoder().withoutPadding().encodeToString(src);
    }

    /**
     * Generates a time ordered UUID, also known as UUID v6. This type of UUID is well-suited for
     * database primary keys, since it starts with a monotonically increasing timestamp.
     *
     * 

* Our implementation makes the least significant bits completely random, since we have no use for a node identifier * or clock sequence, and we have some code that depends on the LSB being random. This also means that we don't * need to block when two entries have the same millisecond timestamp, as the randomness will distinguish them. * *

* See Peabody for more information. */ public static UUID timeOrderedUUID() { return GENERATOR.next(); } /** * Generates a UUID from a concatenation of UUIDs. */ public static UUID fromConcatenatedUUIDs(UUID... uuids) { Preconditions.checkArgument(uuids.length > 0, "Must have at least one UUID to concatenate"); return UUID.nameUUIDFromBytes( (Arrays.stream(uuids).map(UUID::toString).reduce("", String::concat)) .getBytes(StandardCharsets.UTF_8)); } @VisibleForTesting static class Generator { private static final long EPOCH_OFFSET = -122192928000000000L; private final SecureRandom random = new SecureRandom(); private final Clock clock; public Generator(Clock clock) { this.clock = clock; } public UUID next() { long t = this.clock.millis() * 10_000 - EPOCH_OFFSET; long msb = ((t << 4) & 0x0ffffffffffff000L) | 0x0000000000006000L | (t & 0x0000000000000fffL); long lsb = (this.random.nextLong() & 0x3fffffffffffffffL) | 0x8000000000000000L; return new UUID(msb, lsb); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy