com.squeakysand.commons.util.UUIDGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of squeakysand-commons Show documentation
Show all versions of squeakysand-commons Show documentation
Classes, interfaces and enums that assist with everyday Java development tasks.
The newest version!
/*
* Copyright 2010-2012 Craig S. Dickson (http://craigsdickson.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.squeakysand.commons.util;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.SecureRandom;
import java.util.StringTokenizer;
/**
* A UUID is a string-based primary key consisting of 32-digits encoded in hexadecimal. The string
* is composed as follows:
*
*
* - Unique down to the millisecond. Digits 1-8 are the hex-encoded lower 32 bits of the
*
System.currentTimeMillis() call.
* - Unique across a cluster. Digits 9-16 are the hex-encoded repretation of the
* 32-bit integer of the underlying IP Address.
* - Unique down to the objects within a JVM. Digits 17-24 are the hex representation of
* the call to
System.identityHashCode(this), which is guaranteed to return
* distinct integers for distinct objects with a JVM.
* - Unique within an abject within a millisecond. Finally, digits 25-32 represent a
* random 32-bit integer generated on every method call using the cryptographically string
*
java.security.SecureRandom class. Thus, multiple calls to the generate
* method in the same millisecond are guaranteed to be unique.
*
*
* Altogether, a UUID created using this algorithm is guaranteed to be unique across all machines in
* a cluster, across all instance of UUID generators within a JVM on a machine, down to the
* millisecond and even down to the individual method call within each millisecond.
*/
public final class UUIDGenerator {
private static UUIDGenerator singleton;
private String midValue;
private SecureRandom seeder;
/**
* Constructor for UUIDGenerator.
*/
private UUIDGenerator() {
super();
// get the InetAddress of the host
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
throw new IllegalStateException("could not create generator: " + e.getMessage());
}
String hexInetAddress = hexFormat(getLong(inet), 8);
// get the hashcode for this object
String thisHashcode = hexFormat(System.identityHashCode(this), 8);
// set up mid value string
midValue = hexInetAddress + thisHashcode;
// load up the randomizer first
seeder = new SecureRandom();
seeder.nextInt();
}
/**
* Generates a globally unique id.
*
* @return the unique id.
*/
public static String generate() {
if (singleton == null) {
singleton = new UUIDGenerator();
}
return singleton.generateUUID();
}
private String generateUUID() {
long timeNow = System.currentTimeMillis();
// get int value as unsigned
int timeLow = (int) timeNow & 0xffffffff;
// get next random value
int node = seeder.nextInt();
return hexFormat(timeLow, 8) + midValue + hexFormat(node, 8);
}
private String hexFormat(int value, int length) {
String hexValue = Integer.toHexString(value);
String padding = "";
while ((padding.length() + hexValue.length()) < length) {
padding = '0' + padding;
}
return padding + hexValue;
}
private String hexFormat(long value, int length) {
String hexValue = Long.toHexString(value);
String padding = "";
while ((padding.length() + hexValue.length()) < length) {
padding = '0' + padding;
}
return padding + hexValue;
}
private long getLong(InetAddress inet) {
StringTokenizer st = new StringTokenizer(inet.getHostAddress(), ".");
String paddedAddress = "";
while (st.hasMoreTokens()) {
String temp = st.nextToken();
while (temp.length() < 3) {
temp = '0' + temp;
}
paddedAddress += temp;
}
return Long.parseLong(paddedAddress);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy