mirror of
https://gitee.com/dromara/MaxKey.git
synced 2025-12-07 01:18:27 +08:00
UUIDV1
UUIDV1
This commit is contained in:
parent
1b2f924f7e
commit
40bef5723d
58
maxkey-core/src/main/java/org/maxkey/uuid/NodeIDGetter.java
Normal file
58
maxkey-core/src/main/java/org/maxkey/uuid/NodeIDGetter.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package org.maxkey.uuid;
|
||||||
|
//$Id$
|
||||||
|
|
||||||
|
//
|
||||||
|
//(C) Copyright 2005 VeriSign, Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//VeriSign, Inc. shall have no responsibility, financial or
|
||||||
|
//otherwise, for any consequences arising out of the use of
|
||||||
|
//this material. The program material is provided on an "AS IS"
|
||||||
|
//BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||||
|
//express or implied. The user is responsible for determining
|
||||||
|
//any necessary third party rights or authorizations that may
|
||||||
|
//be required for the use of the materials. Users are advised
|
||||||
|
//that they may need authorizations under certain patents from
|
||||||
|
//Microsoft and IBM, or others. Please see notice.txt file.
|
||||||
|
//VeriSign disclaims any obligation to notify the user of any
|
||||||
|
//such third party rights.
|
||||||
|
//
|
||||||
|
|
||||||
|
public class NodeIDGetter
|
||||||
|
{
|
||||||
|
private static Object lock = new Object();
|
||||||
|
private static byte[] nodeID = null;
|
||||||
|
|
||||||
|
private NodeIDGetter() { throw new Error(); }
|
||||||
|
|
||||||
|
private static native void getNodeID(byte[] nodeID);
|
||||||
|
|
||||||
|
public static byte[] getNodeID()
|
||||||
|
{
|
||||||
|
if(nodeID == null) {
|
||||||
|
synchronized(lock) {
|
||||||
|
if(nodeID == null) {
|
||||||
|
try {
|
||||||
|
byte[] data = new UUID("00000000-0000-0000-0000-"
|
||||||
|
+ System.getProperty("org.apache.tsik.uuid.nodeid")).toByteArray();
|
||||||
|
nodeID = new byte[6];
|
||||||
|
System.arraycopy(data, 10, nodeID, 0, 6);
|
||||||
|
return nodeID;
|
||||||
|
} catch(Exception ex) {
|
||||||
|
// phooey.
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
System.loadLibrary("NodeIDGetter");
|
||||||
|
nodeID = new byte[6];
|
||||||
|
getNodeID(nodeID);
|
||||||
|
} catch(LinkageError ex) {
|
||||||
|
// phooey again.
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeID = UUIDRandomness.randomNodeID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nodeID;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
package org.maxkey.uuid;
|
||||||
|
//$Id$
|
||||||
|
|
||||||
|
//
|
||||||
|
//(C) Copyright 2005 VeriSign, Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//VeriSign, Inc. shall have no responsibility, financial or
|
||||||
|
//otherwise, for any consequences arising out of the use of
|
||||||
|
//this material. The program material is provided on an "AS IS"
|
||||||
|
//BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||||
|
//express or implied. The user is responsible for determining
|
||||||
|
//any necessary third party rights or authorizations that may
|
||||||
|
//be required for the use of the materials. Users are advised
|
||||||
|
//that they may need authorizations under certain patents from
|
||||||
|
//Microsoft and IBM, or others. Please see notice.txt file.
|
||||||
|
//VeriSign disclaims any obligation to notify the user of any
|
||||||
|
//such third party rights.
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A more solid timestamp-based UUID generator, this one keeps its
|
||||||
|
* timestamps within a millisecond or so of the current time, and is
|
||||||
|
* thread-safe.
|
||||||
|
*/
|
||||||
|
public class TimestampUUIDGenerator
|
||||||
|
extends UnsynchronizedTimestampUUIDGenerator
|
||||||
|
implements UUIDGenerator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Creates a UUIDGenerator with the specified clock sequence number
|
||||||
|
* and node ID.
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if node == null
|
||||||
|
* @throws IllegalArgumentException if clock_sequence is out of
|
||||||
|
* range or node.length != 6
|
||||||
|
*/
|
||||||
|
public TimestampUUIDGenerator(int clock_sequence,
|
||||||
|
byte[] node)
|
||||||
|
{
|
||||||
|
super(clock_sequence, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a new UUID.
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if adjustmentOverflow() throws it
|
||||||
|
*/
|
||||||
|
public UUID nextUUID()
|
||||||
|
{
|
||||||
|
synchronized(this) {
|
||||||
|
checkSystemTime();
|
||||||
|
return super.nextUUID();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
363
maxkey-core/src/main/java/org/maxkey/uuid/UUID.java
Normal file
363
maxkey-core/src/main/java/org/maxkey/uuid/UUID.java
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
package org.maxkey.uuid;
|
||||||
|
|
||||||
|
//$Id$
|
||||||
|
|
||||||
|
//
|
||||||
|
//(C) Copyright 2005 VeriSign, Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//VeriSign, Inc. shall have no responsibility, financial or
|
||||||
|
//otherwise, for any consequences arising out of the use of
|
||||||
|
//this material. The program material is provided on an "AS IS"
|
||||||
|
//BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||||
|
//express or implied. The user is responsible for determining
|
||||||
|
//any necessary third party rights or authorizations that may
|
||||||
|
//be required for the use of the materials. Users are advised
|
||||||
|
//that they may need authorizations under certain patents from
|
||||||
|
//Microsoft and IBM, or others. Please see notice.txt file.
|
||||||
|
//VeriSign disclaims any obligation to notify the user of any
|
||||||
|
//such third party rights.
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immutable representation of a Universally Unique Identifier (UUID),
|
||||||
|
* also known (less presumptuously) as a Globally Unique Identifier (GUID).
|
||||||
|
* These identifiers can be generated in a distributed fashion without
|
||||||
|
* central coordination, and are reasonably small (128 bits), making them
|
||||||
|
* suitable for a wide range of purposes.
|
||||||
|
*
|
||||||
|
* @see http://www.opengroup.org/onlinepubs/9629399/apdxa.htm
|
||||||
|
* @see http://www.ics.uci.edu/~ejw/authoring/uuid-guid/draft-leach-uuids-guids-01.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.security.MessageDigest;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
public final class UUID implements Serializable
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 687078561200656066L;
|
||||||
|
// Format variants.
|
||||||
|
public static final int VARIANT_NCS = 0x00;
|
||||||
|
public static final int VARIANT_NCS_MASK = 0x80;
|
||||||
|
public static final int VARIANT_DCE = 0x80;
|
||||||
|
public static final int VARIANT_DCE_MASK = 0xC0;
|
||||||
|
public static final int VARIANT_MICROSOFT = 0xC0;
|
||||||
|
public static final int VARIANT_MICROSOFT_MASK = 0xE0;
|
||||||
|
public static final int VARIANT_RESERVED = 0xE0;
|
||||||
|
public static final int VARIANT_RESERVED_MASK = 0xE0;
|
||||||
|
|
||||||
|
// Version numbers for VARIANT_DCE.
|
||||||
|
public static final int VERSION_TIMESTAMP = 0x1000;
|
||||||
|
public static final int VERSION_UID = 0x2000;
|
||||||
|
public static final int VERSION_NAME = 0x3000;
|
||||||
|
public static final int VERSION_RANDOM = 0x4000;
|
||||||
|
public static final int VERSION_MASK = 0xF000;
|
||||||
|
|
||||||
|
// Data representing the UUID.
|
||||||
|
private transient int time_low;
|
||||||
|
private transient short time_mid, time_hi_and_version;
|
||||||
|
private transient byte clock_seq_hi_and_reserved;
|
||||||
|
private transient byte clock_seq_low;
|
||||||
|
private transient byte[] node;
|
||||||
|
|
||||||
|
// Some annotations so we don't have to compute them multiple times.
|
||||||
|
private transient int hash_code;
|
||||||
|
private transient String string_rep;
|
||||||
|
private transient byte[] binary_rep;
|
||||||
|
|
||||||
|
private static UUIDGenerator default_generator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The distinguished nil UUID, one whose bits are all zeroes.
|
||||||
|
*/
|
||||||
|
public static final UUID nil = new UUID((int)0,
|
||||||
|
(short)0,
|
||||||
|
(short)0,
|
||||||
|
(byte)0,
|
||||||
|
(byte)0,
|
||||||
|
new byte[] { 0, 0, 0, 0, 0, 0 });
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new UUID with the specified value.
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if node is null
|
||||||
|
* @throws IllegalArgumentException if node.length != 6
|
||||||
|
*/
|
||||||
|
public UUID(int time_low,
|
||||||
|
short time_mid,
|
||||||
|
short time_hi_and_version,
|
||||||
|
byte clock_seq_low,
|
||||||
|
byte clock_seq_hi_and_reserved,
|
||||||
|
byte[] node)
|
||||||
|
throws NullPointerException, IllegalArgumentException
|
||||||
|
{
|
||||||
|
if(node == null) throw new NullPointerException();
|
||||||
|
if(node.length != 6) throw new IllegalArgumentException();
|
||||||
|
|
||||||
|
this.time_low = time_low;
|
||||||
|
this.time_mid = time_mid;
|
||||||
|
this.time_hi_and_version = time_hi_and_version;
|
||||||
|
this.clock_seq_low = clock_seq_low;
|
||||||
|
this.clock_seq_hi_and_reserved = clock_seq_hi_and_reserved;
|
||||||
|
this.node = new byte[6];
|
||||||
|
System.arraycopy(node, 0, this.node, 0, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a UUID from its string representation.
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if s is null
|
||||||
|
* @throws IllegalArgumentException if s.length() != 36 or any expected hyphens are missing
|
||||||
|
* @throws NumberFormatException if an expected hex digit isn't one
|
||||||
|
*/
|
||||||
|
public UUID(String s)
|
||||||
|
throws NullPointerException,
|
||||||
|
IllegalArgumentException,
|
||||||
|
NumberFormatException
|
||||||
|
{
|
||||||
|
if(s == null) throw new NullPointerException();
|
||||||
|
if(s.length() != 36) throw new IllegalArgumentException();
|
||||||
|
time_low = parseHex(s.substring(0, 8));
|
||||||
|
if(s.charAt(8) != '-') throw new IllegalArgumentException();
|
||||||
|
time_mid = (short) parseHex(s.substring(9, 13));
|
||||||
|
if(s.charAt(13) != '-') throw new IllegalArgumentException();
|
||||||
|
time_hi_and_version = (short) parseHex(s.substring(14, 18));
|
||||||
|
if(s.charAt(18) != '-') throw new IllegalArgumentException();
|
||||||
|
clock_seq_hi_and_reserved = (byte) parseHex(s.substring(19, 21));
|
||||||
|
clock_seq_low = (byte) parseHex(s.substring(21, 23));
|
||||||
|
if(s.charAt(23) != '-') throw new IllegalArgumentException();
|
||||||
|
node = new byte[6];
|
||||||
|
for(int i = 0; i < 6; i++)
|
||||||
|
node[i] = (byte) parseHex(s.substring(2 * i + 24, 2 * i + 26));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the 16 bytes of a UUID from the specified
|
||||||
|
* DataInput source.
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if in == null
|
||||||
|
* @throws IOException if the read fails
|
||||||
|
*/
|
||||||
|
public UUID(DataInput in) throws IOException
|
||||||
|
{
|
||||||
|
if(in == null) throw new NullPointerException();
|
||||||
|
readData(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a UUID from 16 data bytes.
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if data == null
|
||||||
|
* @throws IllegalArgumentException if data.length != 16
|
||||||
|
*/
|
||||||
|
public UUID(byte[] data)
|
||||||
|
{
|
||||||
|
if(data == null) throw new NullPointerException();
|
||||||
|
if(data.length != 16) throw new IllegalArgumentException();
|
||||||
|
try {
|
||||||
|
readData(new DataInputStream(new ByteArrayInputStream(data)));
|
||||||
|
} catch(IOException ex) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readData(DataInput in) throws IOException
|
||||||
|
{
|
||||||
|
time_low = in.readInt();
|
||||||
|
time_mid = in.readShort();
|
||||||
|
time_hi_and_version = in.readShort();
|
||||||
|
clock_seq_hi_and_reserved = in.readByte();
|
||||||
|
clock_seq_low = in.readByte();
|
||||||
|
node = new byte[6];
|
||||||
|
in.readFully(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
|
||||||
|
{
|
||||||
|
readData(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the 16 data bytes of this UUID to the specified
|
||||||
|
* DataOutput interface.
|
||||||
|
*
|
||||||
|
* @throws IOException if the DataOutput interface does
|
||||||
|
*/
|
||||||
|
public void writeData(DataOutput out) throws IOException
|
||||||
|
{
|
||||||
|
out.writeInt(time_low);
|
||||||
|
out.writeShort(time_mid);
|
||||||
|
out.writeShort(time_hi_and_version);
|
||||||
|
out.writeByte(clock_seq_hi_and_reserved);
|
||||||
|
out.writeByte(clock_seq_low);
|
||||||
|
out.write(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeObject(ObjectOutputStream out) throws IOException
|
||||||
|
{
|
||||||
|
writeData(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns true if two UUIDs are equal by value.
|
||||||
|
*/
|
||||||
|
public boolean equals(Object obj)
|
||||||
|
{
|
||||||
|
if(obj == null || !(obj instanceof UUID))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UUID other = (UUID) obj;
|
||||||
|
|
||||||
|
if(this == other) return true;
|
||||||
|
|
||||||
|
if(hash_code != 0 &&
|
||||||
|
other.hash_code != 0 &&
|
||||||
|
hash_code != other.hash_code)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return
|
||||||
|
time_low == other.time_low &&
|
||||||
|
time_mid == other.time_mid &&
|
||||||
|
time_hi_and_version == other.time_hi_and_version &&
|
||||||
|
clock_seq_low == other.clock_seq_low &&
|
||||||
|
clock_seq_hi_and_reserved == other.clock_seq_hi_and_reserved &&
|
||||||
|
Arrays.equals(node, other.node);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a hash code for this UUID.
|
||||||
|
*/
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
if(hash_code == 0) {
|
||||||
|
synchronized(this) {
|
||||||
|
if(hash_code == 0) {
|
||||||
|
hash_code = toString().hashCode();
|
||||||
|
if(hash_code == 0)
|
||||||
|
hash_code = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hash_code;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method for toString().
|
||||||
|
*/
|
||||||
|
private static void appendHex(StringBuffer sb, long num, int digits)
|
||||||
|
{
|
||||||
|
if(digits > 0 && digits < 16)
|
||||||
|
num = num & ((1L << (digits * 4)) - 1);
|
||||||
|
|
||||||
|
String str = Long.toHexString(num);
|
||||||
|
int len = str.length();
|
||||||
|
while(len < digits) {
|
||||||
|
sb.append('0');
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
sb.append(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method for UUID(String) constructor.
|
||||||
|
*/
|
||||||
|
private static int parseHex(String s) throws NumberFormatException
|
||||||
|
{
|
||||||
|
if(s.charAt(0) == '-')
|
||||||
|
throw new NumberFormatException();
|
||||||
|
|
||||||
|
return Integer.parseInt(s, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the string representation of this UUID.
|
||||||
|
*/
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
if(string_rep == null) {
|
||||||
|
synchronized(this) {
|
||||||
|
if(string_rep == null) {
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
appendHex(sb, time_low, 8);
|
||||||
|
sb.append('-');
|
||||||
|
appendHex(sb, time_mid, 4);
|
||||||
|
sb.append('-');
|
||||||
|
appendHex(sb, time_hi_and_version, 4);
|
||||||
|
sb.append('-');
|
||||||
|
appendHex(sb, clock_seq_hi_and_reserved, 2);
|
||||||
|
appendHex(sb, clock_seq_low, 2);
|
||||||
|
sb.append('-');
|
||||||
|
for(int i = 0; i < 6; i++)
|
||||||
|
appendHex(sb, node[i], 2);
|
||||||
|
string_rep = sb.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string_rep;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of 16 bytes containing the binary representation
|
||||||
|
* of this UUID.
|
||||||
|
*/
|
||||||
|
public byte[] toByteArray()
|
||||||
|
{
|
||||||
|
if(binary_rep == null) {
|
||||||
|
synchronized(this) {
|
||||||
|
if(binary_rep == null) {
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream(16);
|
||||||
|
writeData(new DataOutputStream(baos));
|
||||||
|
binary_rep = baos.toByteArray();
|
||||||
|
} catch(IOException ex) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (byte[]) binary_rep.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new, unique UUID.
|
||||||
|
*/
|
||||||
|
public static UUID generate()
|
||||||
|
{
|
||||||
|
if(default_generator == null)
|
||||||
|
default_generator = new TimestampUUIDGenerator(UUIDRandomness.randomClockSequence(), NodeIDGetter.getNodeID());
|
||||||
|
|
||||||
|
return default_generator.nextUUID();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a UUID based on a hash of a namespace designator
|
||||||
|
* UUID and a name.
|
||||||
|
*/
|
||||||
|
public static UUID fromName(UUID namespace, String name)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
DataOutputStream dos = new DataOutputStream(baos);
|
||||||
|
|
||||||
|
namespace.writeData(dos);
|
||||||
|
dos.flush();
|
||||||
|
md5.update(baos.toByteArray());
|
||||||
|
baos.reset();
|
||||||
|
dos.writeUTF(name);
|
||||||
|
dos.flush();
|
||||||
|
byte[] data = baos.toByteArray();
|
||||||
|
md5.update(data, 2, data.length - 2);
|
||||||
|
data = md5.digest(); // this should be 16 bytes
|
||||||
|
UUID uuid = new UUID(data);
|
||||||
|
uuid.clock_seq_hi_and_reserved = (byte) ((uuid.clock_seq_hi_and_reserved & ~VARIANT_DCE_MASK) | VARIANT_DCE);
|
||||||
|
uuid.time_hi_and_version = (short) ((uuid.time_hi_and_version & ~VERSION_MASK) | VERSION_NAME);
|
||||||
|
return uuid;
|
||||||
|
} catch(Exception ex) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
maxkey-core/src/main/java/org/maxkey/uuid/UUIDGenerator.java
Normal file
12
maxkey-core/src/main/java/org/maxkey/uuid/UUIDGenerator.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package org.maxkey.uuid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface representing an object that generates UUIDs.
|
||||||
|
*/
|
||||||
|
public interface UUIDGenerator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Generates a new unique UUID according to this generator's rules.
|
||||||
|
*/
|
||||||
|
UUID nextUUID();
|
||||||
|
}
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
// $Id$
|
||||||
|
|
||||||
|
//
|
||||||
|
// (C) Copyright 2005 VeriSign, Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
// VeriSign, Inc. shall have no responsibility, financial or
|
||||||
|
// otherwise, for any consequences arising out of the use of
|
||||||
|
// this material. The program material is provided on an "AS IS"
|
||||||
|
// BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||||
|
// express or implied. The user is responsible for determining
|
||||||
|
// any necessary third party rights or authorizations that may
|
||||||
|
// be required for the use of the materials. Users are advised
|
||||||
|
// that they may need authorizations under certain patents from
|
||||||
|
// Microsoft and IBM, or others. Please see notice.txt file.
|
||||||
|
// VeriSign disclaims any obligation to notify the user of any
|
||||||
|
// such third party rights.
|
||||||
|
//
|
||||||
|
|
||||||
|
package org.maxkey.uuid;
|
||||||
|
|
||||||
|
import java.security.*;
|
||||||
|
|
||||||
|
public final class UUIDRandomness
|
||||||
|
{
|
||||||
|
static SecureRandom random = new SecureRandom();
|
||||||
|
|
||||||
|
private UUIDRandomness()
|
||||||
|
{
|
||||||
|
throw new Error();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] randomNodeID()
|
||||||
|
{
|
||||||
|
byte[] id = new byte[6];
|
||||||
|
synchronized(random) {
|
||||||
|
random.nextBytes(id);
|
||||||
|
}
|
||||||
|
id[0] |= 0x01;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int randomClockSequence()
|
||||||
|
{
|
||||||
|
synchronized(random) {
|
||||||
|
return random.nextInt(16384);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int nextRandomClockSequence(int prev)
|
||||||
|
{
|
||||||
|
int next;
|
||||||
|
synchronized(random) {
|
||||||
|
next = random.nextInt(16383);
|
||||||
|
}
|
||||||
|
if(next >= prev) next++;
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,114 @@
|
|||||||
|
package org.maxkey.uuid;
|
||||||
|
|
||||||
|
//$Id$
|
||||||
|
|
||||||
|
//
|
||||||
|
//(C) Copyright 2005 VeriSign, Inc. All Rights Reserved.
|
||||||
|
//
|
||||||
|
//VeriSign, Inc. shall have no responsibility, financial or
|
||||||
|
//otherwise, for any consequences arising out of the use of
|
||||||
|
//this material. The program material is provided on an "AS IS"
|
||||||
|
//BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
||||||
|
//express or implied. The user is responsible for determining
|
||||||
|
//any necessary third party rights or authorizations that may
|
||||||
|
//be required for the use of the materials. Users are advised
|
||||||
|
//that they may need authorizations under certain patents from
|
||||||
|
//Microsoft and IBM, or others. Please see notice.txt file.
|
||||||
|
//VeriSign disclaims any obligation to notify the user of any
|
||||||
|
//such third party rights.
|
||||||
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As simple and fast of a timestamp-based UUIDGenerator as is practical.
|
||||||
|
* This class is not thread-safe, and the timestamp field in its UUIDs is
|
||||||
|
* not reliably close to the actual time.
|
||||||
|
*/
|
||||||
|
public class UnsynchronizedTimestampUUIDGenerator implements UUIDGenerator
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Number of milliseconds between the Gregorian calendar
|
||||||
|
* cutover and the Unix epoch.
|
||||||
|
*/
|
||||||
|
public static final long EPOCH_OFFSET = 12219292800000L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of units of UUID time resolution per unit of system
|
||||||
|
* clock resolution.
|
||||||
|
*/
|
||||||
|
public static final long CLOCK_RES = 10000L;
|
||||||
|
|
||||||
|
protected long last_time;
|
||||||
|
protected long clock_adj;
|
||||||
|
protected int clock_sequence;
|
||||||
|
protected byte[] node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a UUIDGenerator with the specified clock sequence number
|
||||||
|
* and node ID.
|
||||||
|
*
|
||||||
|
* @throws NullPointerException if node == null
|
||||||
|
* @throws IllegalArgumentException if clock_sequence is out of range or node.length != 6
|
||||||
|
*/
|
||||||
|
public UnsynchronizedTimestampUUIDGenerator(int clock_sequence,
|
||||||
|
byte[] node)
|
||||||
|
{
|
||||||
|
if(clock_sequence < 0 || clock_sequence >= 16384)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
if(node == null)
|
||||||
|
throw new NullPointerException();
|
||||||
|
if(node.length != 6)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
|
||||||
|
this.clock_sequence = clock_sequence;
|
||||||
|
this.node = (byte[]) node.clone();
|
||||||
|
checkSystemTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the current system time and updates last_time, clock_sequence
|
||||||
|
* and clock_adj based on it.
|
||||||
|
*/
|
||||||
|
protected void checkSystemTime() {
|
||||||
|
long sys_time = System.currentTimeMillis();
|
||||||
|
|
||||||
|
/* If monotonicity is lost, bump clock_sequence. */
|
||||||
|
if(sys_time < last_time)
|
||||||
|
clock_sequence = UUIDRandomness.nextRandomClockSequence(clock_sequence);
|
||||||
|
|
||||||
|
/* If the clock ticked, clear the adjustment. */
|
||||||
|
if(sys_time != last_time) {
|
||||||
|
last_time = sys_time;
|
||||||
|
clock_adj = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when clock_adj >= CLOCK_RES, expected to take corrective action.
|
||||||
|
* May throw an IllegalStateException if corrective action fails.
|
||||||
|
*/
|
||||||
|
protected void adjustmentOverflow() throws IllegalStateException
|
||||||
|
{
|
||||||
|
checkSystemTime();
|
||||||
|
if(clock_adj >= CLOCK_RES)
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a new UUID.
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException if adjustmentOverflow() throws it
|
||||||
|
*/
|
||||||
|
public UUID nextUUID()
|
||||||
|
{
|
||||||
|
long unique_time = (last_time + EPOCH_OFFSET) * CLOCK_RES + clock_adj;
|
||||||
|
if(++clock_adj > CLOCK_RES) adjustmentOverflow();
|
||||||
|
|
||||||
|
return new UUID((int) (unique_time & 0xFFFFFFFF),
|
||||||
|
(short) ((unique_time >> 32) & 0xFFFF),
|
||||||
|
(short) (((unique_time >> 48) & 0x0FFF) | UUID.VERSION_TIMESTAMP),
|
||||||
|
(byte) (clock_sequence & 0xFF),
|
||||||
|
(byte) (((clock_sequence >> 8) & 0x3F) | UUID.VARIANT_DCE),
|
||||||
|
node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -3,7 +3,7 @@ package com.connsec.util;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
//import java.util.UUID;
|
//import java.util.UUID;
|
||||||
|
|
||||||
import org.apache.tsik.uuid.UUID;
|
import org.maxkey.uuid.UUID;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.maxkey.util.UUIDGenerator;
|
import org.maxkey.util.UUIDGenerator;
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
2
maxkey-protocols/maxkey-protocol-tokenbased/bin/main/.gitignore
vendored
Normal file
2
maxkey-protocols/maxkey-protocol-tokenbased/bin/main/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/META-INF/
|
||||||
|
/org/
|
||||||
Loading…
x
Reference in New Issue
Block a user