可以用标准的guiidgen程序,以前的帖子上好像有,你可以在Google上查询一下guid gen java,应该有。 如果不嫌弃,我这个程序也可以凑活用: //返回长度为length个字符的独一无二字串 public static String genUniqueID(String a) { Date now = new Date(); String a = "" + now.getTime() + Math.random(); String result = a.hashCode(); return result; }
修订一下: public static String genUniqueID() { Date now = new Date(); String a = "" + now.getTime() + Math.random(); String result = a.hashCode(); return result; }
也补一个. public static String getId() { Date nowdate=new Date(); long timenow=nowdate.getTime(); String id=String.valueOf(timenow); return id; }
package tyrex.services; import java.util.Properties; import java.util.Random; import java.util.Date; import java.util.HashSet; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.StringTokenizer; import tyrex.util.Configuration; import tyrex.util.Logger; import tyrex.util.Messages;public final class UUID { /** * Default prefix that can be used by identifiers. * This prefix is not added to identifiers created using {@link * #create() create}. Identifiers created using {@link * #create(String) create(String)} may use this prefix to * denote an identifier. The value of this variable is * <code>ID:</code>. */ public static final String PREFIX = "ID:"; /** * The identifier resolution in bytes. Identifiers are 16-byte * long, or 128 bits. Without a prefix, an identifier can be * represented as 36 hexadecimal digits and hyphens. * (4 hyphens are used in the UUID format) */ public static final int RESOLUTION_BYTES = 16; /** * The maximum length of an identifier in textual form. * Prefixed identifiers and application identifiers must be * less or equal to the maximum length to allow persistence. * This maximum length is 64 characters. */ public static final int MAXIMUM_LENGTH = 64; /** * The maximum length of an identifier prefix. Identifiers * created using {@link #create(String) create(String)} with * a prefix that is no longer than the maximum prefix size * are guaranteed to be within the maximum length allowed * and need not be trimmed. */ public static final int MAXIMUM_PREFIX = 28; /** * UUID state file property that determined the node identifier. * The value of this property is an hexadecimal 47-bit value. * The name of this property is <tt>uuid.nodeIdentifier</tt>. */ public static final String PROPERTY_NODE_IDENTIFIER = "uuid.nodeIdentifier"; /** * UUID state file property that determined the clock sequence. * The value of this property is an hexadecimal 12-bit value. * The name of this property is <tt>uuid.clockSequence</tt>. */ public static final String PROPERTY_CLOCK_SEQUENCE = "uuid.clockSequence"; /** * Name of the UUID state file. If no file was specified in the * configuration properties, this file name is used. The file * name is <tt>uuid.state</tt>. */ public static final String UUID_STATE_FILE = "uuid.state"; /** * The variant value determines the layout of the UUID. This * variant is specified in the IETF February 4, 1998 draft. * Used for character octets. */ private static final int UUID_VARIANT_OCTET = 0x08; /** * The variant value determines the layout of the UUID. This * variant is specified in the IETF February 4, 1998 draft. * Used for byte array. */ private static final int UUID_VARIANT_BYTE = 0x80; /** * The version identifier for a time-based UUID. This version * is specified in the IETF February 4, 1998 draft. Used for * character octets. */ private static final int UUID_VERSION_CLOCK_OCTET = 0x01; /** * The version identifier for a time-based UUID. This version * is specified in the IETF February 4, 1998 draft. Used for * byte array. */ private static final int UUID_VERSION_CLOCK_BYTE = 0x10; /** * The version identifier for a name-based UUID. This version * is specified in the IETF February 4, 1998 draft. Used for * character octets. */ private static final int UUID_VERSION_NAME_OCTET = 0x03; /** * The version identifier for a name-based UUID. This version * is specified in the IETF February 4, 1998 draft. Used for * byte array. */ private static final int UUID_VERSION_NAME_BYTE = 0x30; /** * The version identifier for a random-based UUID. This version * is specified in the IETF February 4, 1998 draft. Used for * character octets. */ private static final int UUID_VERSION_RANDOM_CLOCK = 0x04; /** * The version identifier for a random-based UUID. This version * is specified in the IETF February 4, 1998 draft. Used for * byte array. */ private static final int UUID_VERSION_RANDOM_BYTE = 0x40; /** * The difference between Java clock and UUID clock. Java clock * is base time is January 1, 1970. UUID clock base time is * October 15, 1582. */ private static final long JAVA_UUID_CLOCK_DIFF = 0x0b1d069b5400L; /** * Efficient mapping from 4 bit value to lower case hexadecimal digit. */ private final static char[] HEX_DIGITS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; /** * The number of UUIDs that can be generated per clock tick. * UUID assumes a clock tick every 100 nanoseconds. The actual * clock ticks are measured in milliseconds and based on the * sync-every property of the clock. The product of these two * values is used to set this variable. */ private static int _uuidsPerTick; /** * The number of UUIDs generated in this clock tick. This counter * is reset each time the clock is advanced a tick. When it reaches * the maximum number of UUIDs allowed per tick, we block until the * clock advances. */ private static int _uuidsThisTick; /** * The last clock. Whenever the clock changes, we record the last clock * to identify when we get a new clock, or when we should increments * the UUIDs per tick counter. */ private static long _lastClock; /** * The clock sequence. The clock sequence is obtained from the UUID * properties and incremented by one each time we boot, or is * generated randomaly if missing in the UUID properties. The clock * sequence is made of four hexadecimal digits. */ private static char[] _clockSeqOctet; /** * The clock sequence. The clock sequence is obtained from the UUID * properties and incremented by one each time we boot, or is * generated randomaly if missing in the UUID properties. The clock * sequence is made of two bytes. */ private static byte[] _clockSeqByte; /** * The node identifier. The node identifier is obtained from the * UUID properties, or is generated if missing in the UUID properties. * The node identifier is made of twelve hexadecimal digits. */ private static char[] _nodeIdentifierOctet; /** * The node identifier. The node identifier is obtained from the * UUID properties, or is generated if missing in the UUID properties. * The node identifier is made of six bytes. */ private static byte[] _nodeIdentifierByte; /** * Creates and returns a new identifier. * * @return An identifier */ public static String create() { return String.valueOf( createTimeUUIDChars() ); }
/** * Creates and returns a new prefixed identifier. * <p> * This method is equivalent to <code>prefix + create()</code>. * * @param prefix The prefix to use * @return A prefixed identifier */ public static String create( String prefix ) { StringBuffer buffer; if ( prefix == null ) throw new IllegalArgumentException( "Argument prefix is null" ); buffer = new StringBuffer( MAXIMUM_LENGTH - MAXIMUM_PREFIX + prefix.length() ); buffer.append( prefix ); buffer.append( createTimeUUIDChars() ); return buffer.toString(); } /** * Creates and returns a new identifier. * * @return An identifier */ public static byte[] createBinary() { return createTimeUUIDBytes(); } /** * Converts a prefixed identifier into a byte array. An exception * is thrown if the identifier does not match the excepted textual * encoding. * <p> * The format for the identifier is <code>prefix{nn|-}*</code>: * a prefix followed by a sequence of bytes, optionally separated * by hyphens. Each byte is encoded as a pair of hexadecimal digits. * * @param prefix The identifier prefix * @param identifier The prefixed identifier * @return The identifier as an array of bytes * @throws InvalidIDException The identifier does not begin with * the prefix, or does not consist of a sequence of hexadecimal * digit pairs, optionally separated by hyphens */ public static byte[] toBytes( String prefix, String identifier ) throws InvalidIDException { int index; char digit; byte nibble; byte[] bytes; byte[] newBytes; if ( identifier == null ) throw new IllegalArgumentException( "Argument identifier is null" ); if ( prefix == null ) throw new IllegalArgumentException( "Argument prefix is null" ); if ( ! identifier.startsWith( prefix ) ) throw new InvalidIDException( Messages.format( "tyrex.util.idInvalidPrefix", prefix, identifier ) ); index = 0; bytes = new byte[ ( identifier.length() - prefix.length() ) / 2 ]; for ( int i = prefix.length() ; i < identifier.length() ; ++i ) { digit = identifier.charAt( i ); if ( digit == '-' ) continue; if ( digit >= '0' && digit <= '9' ) nibble = (byte) ( ( digit - '0' ) << 4 ); else if ( digit >= 'A' && digit <= 'F' ) nibble = (byte) ( ( digit - ( 'A' - 0x0A ) ) << 4 ); else if ( digit >= 'a' && digit <= 'f' ) nibble = (byte) ( ( digit - ( 'a' - 0x0A ) ) << 4 ); else throw new InvalidIDException( Messages.format( "tyrex.util.idInvalidCharacter", String.valueOf( digit ), identifier ) ); ++i; if ( i == identifier.length() ) throw new InvalidIDException( Messages.format( "tyrex.util.idInvalidOddDigits", identifier ) ); digit = identifier.charAt( i ); if ( digit >= '0' && digit <= '9' ) nibble = (byte) ( nibble | ( digit - '0' ) ); else if ( digit >= 'A' && digit <= 'F' ) nibble = (byte) ( nibble | ( digit - ( 'A' - 0x0A ) ) ); else if ( digit >= 'a' && digit <= 'f' ) nibble = (byte) ( nibble | ( digit - ( 'a' - 0x0A ) ) ); else throw new InvalidIDException( Messages.format( "tyrex.util.idInvalidCharacter", String.valueOf( digit ), identifier ) ); bytes[ index ] = nibble; ++index; } if ( index == bytes.length ) return bytes; newBytes = new byte[ index ]; while ( index-- > 0 ) newBytes[ index ] = bytes[ index ]; return newBytes; }
如果不嫌弃,我这个程序也可以凑活用:
//返回长度为length个字符的独一无二字串
public static String genUniqueID(String a) {
Date now = new Date();
String a = "" + now.getTime() + Math.random();
String result = a.hashCode();
return result;
}
public static String genUniqueID() {
Date now = new Date();
String a = "" + now.getTime() + Math.random();
String result = a.hashCode();
return result;
}
public static String getId()
{
Date nowdate=new Date();
long timenow=nowdate.getTime();
String id=String.valueOf(timenow);
return id;
}
public static String getUniqueId(){
VMID vmid=new VMID();
return vmid.toString();
}
jdk号称用该方法得到的ID是唯一的,但我不知道在同一台机器上,在完全相同的时间内,会不会得到不同的结果。
确实不是绝对的,但是可靠性已经达到了绝对的程度。
具体证明和概率有关。
就是SQL SERVER上的全球唯一号了。
guid的算法是怎样实现的?
import java.util.Properties;
import java.util.Random;
import java.util.Date;
import java.util.HashSet;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.StringTokenizer;
import tyrex.util.Configuration;
import tyrex.util.Logger;
import tyrex.util.Messages;public final class UUID
{
/**
* Default prefix that can be used by identifiers.
* This prefix is not added to identifiers created using {@link
* #create() create}. Identifiers created using {@link
* #create(String) create(String)} may use this prefix to
* denote an identifier. The value of this variable is
* <code>ID:</code>.
*/
public static final String PREFIX = "ID:";
/**
* The identifier resolution in bytes. Identifiers are 16-byte
* long, or 128 bits. Without a prefix, an identifier can be
* represented as 36 hexadecimal digits and hyphens.
* (4 hyphens are used in the UUID format)
*/
public static final int RESOLUTION_BYTES = 16;
/**
* The maximum length of an identifier in textual form.
* Prefixed identifiers and application identifiers must be
* less or equal to the maximum length to allow persistence.
* This maximum length is 64 characters.
*/
public static final int MAXIMUM_LENGTH = 64;
/**
* The maximum length of an identifier prefix. Identifiers
* created using {@link #create(String) create(String)} with
* a prefix that is no longer than the maximum prefix size
* are guaranteed to be within the maximum length allowed
* and need not be trimmed.
*/
public static final int MAXIMUM_PREFIX = 28;
/**
* UUID state file property that determined the node identifier.
* The value of this property is an hexadecimal 47-bit value.
* The name of this property is <tt>uuid.nodeIdentifier</tt>.
*/
public static final String PROPERTY_NODE_IDENTIFIER = "uuid.nodeIdentifier";
/**
* UUID state file property that determined the clock sequence.
* The value of this property is an hexadecimal 12-bit value.
* The name of this property is <tt>uuid.clockSequence</tt>.
*/
public static final String PROPERTY_CLOCK_SEQUENCE = "uuid.clockSequence";
/**
* Name of the UUID state file. If no file was specified in the
* configuration properties, this file name is used. The file
* name is <tt>uuid.state</tt>.
*/
public static final String UUID_STATE_FILE = "uuid.state";
/**
* The variant value determines the layout of the UUID. This
* variant is specified in the IETF February 4, 1998 draft.
* Used for character octets.
*/
private static final int UUID_VARIANT_OCTET = 0x08;
/**
* The variant value determines the layout of the UUID. This
* variant is specified in the IETF February 4, 1998 draft.
* Used for byte array.
*/
private static final int UUID_VARIANT_BYTE = 0x80;
/**
* The version identifier for a time-based UUID. This version
* is specified in the IETF February 4, 1998 draft. Used for
* character octets.
*/
private static final int UUID_VERSION_CLOCK_OCTET = 0x01;
/**
* The version identifier for a time-based UUID. This version
* is specified in the IETF February 4, 1998 draft. Used for
* byte array.
*/
private static final int UUID_VERSION_CLOCK_BYTE = 0x10;
/**
* The version identifier for a name-based UUID. This version
* is specified in the IETF February 4, 1998 draft. Used for
* character octets.
*/
private static final int UUID_VERSION_NAME_OCTET = 0x03;
/**
* The version identifier for a name-based UUID. This version
* is specified in the IETF February 4, 1998 draft. Used for
* byte array.
*/
private static final int UUID_VERSION_NAME_BYTE = 0x30;
/**
* The version identifier for a random-based UUID. This version
* is specified in the IETF February 4, 1998 draft. Used for
* character octets.
*/
private static final int UUID_VERSION_RANDOM_CLOCK = 0x04;
/**
* The version identifier for a random-based UUID. This version
* is specified in the IETF February 4, 1998 draft. Used for
* byte array.
*/
private static final int UUID_VERSION_RANDOM_BYTE = 0x40;
/**
* The difference between Java clock and UUID clock. Java clock
* is base time is January 1, 1970. UUID clock base time is
* October 15, 1582.
*/
private static final long JAVA_UUID_CLOCK_DIFF = 0x0b1d069b5400L;
/**
* Efficient mapping from 4 bit value to lower case hexadecimal digit.
*/
private final static char[] HEX_DIGITS = new char[] { '0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
/**
* The number of UUIDs that can be generated per clock tick.
* UUID assumes a clock tick every 100 nanoseconds. The actual
* clock ticks are measured in milliseconds and based on the
* sync-every property of the clock. The product of these two
* values is used to set this variable.
*/
private static int _uuidsPerTick;
/**
* The number of UUIDs generated in this clock tick. This counter
* is reset each time the clock is advanced a tick. When it reaches
* the maximum number of UUIDs allowed per tick, we block until the
* clock advances.
*/
private static int _uuidsThisTick;
/**
* The last clock. Whenever the clock changes, we record the last clock
* to identify when we get a new clock, or when we should increments
* the UUIDs per tick counter.
*/
private static long _lastClock;
/**
* The clock sequence. The clock sequence is obtained from the UUID
* properties and incremented by one each time we boot, or is
* generated randomaly if missing in the UUID properties. The clock
* sequence is made of four hexadecimal digits.
*/
private static char[] _clockSeqOctet;
/**
* The clock sequence. The clock sequence is obtained from the UUID
* properties and incremented by one each time we boot, or is
* generated randomaly if missing in the UUID properties. The clock
* sequence is made of two bytes.
*/
private static byte[] _clockSeqByte;
/**
* The node identifier. The node identifier is obtained from the
* UUID properties, or is generated if missing in the UUID properties.
* The node identifier is made of twelve hexadecimal digits.
*/
private static char[] _nodeIdentifierOctet;
/**
* The node identifier. The node identifier is obtained from the
* UUID properties, or is generated if missing in the UUID properties.
* The node identifier is made of six bytes.
*/
private static byte[] _nodeIdentifierByte;
/**
* Creates and returns a new identifier.
*
* @return An identifier
*/
public static String create()
{
return String.valueOf( createTimeUUIDChars() );
}
* Creates and returns a new prefixed identifier.
* <p>
* This method is equivalent to <code>prefix + create()</code>.
*
* @param prefix The prefix to use
* @return A prefixed identifier
*/
public static String create( String prefix )
{
StringBuffer buffer; if ( prefix == null )
throw new IllegalArgumentException( "Argument prefix is null" );
buffer = new StringBuffer( MAXIMUM_LENGTH - MAXIMUM_PREFIX + prefix.length() );
buffer.append( prefix );
buffer.append( createTimeUUIDChars() );
return buffer.toString();
}
/**
* Creates and returns a new identifier.
*
* @return An identifier
*/
public static byte[] createBinary()
{
return createTimeUUIDBytes();
}
/**
* Converts a prefixed identifier into a byte array. An exception
* is thrown if the identifier does not match the excepted textual
* encoding.
* <p>
* The format for the identifier is <code>prefix{nn|-}*</code>:
* a prefix followed by a sequence of bytes, optionally separated
* by hyphens. Each byte is encoded as a pair of hexadecimal digits.
*
* @param prefix The identifier prefix
* @param identifier The prefixed identifier
* @return The identifier as an array of bytes
* @throws InvalidIDException The identifier does not begin with
* the prefix, or does not consist of a sequence of hexadecimal
* digit pairs, optionally separated by hyphens
*/
public static byte[] toBytes( String prefix, String identifier )
throws InvalidIDException
{
int index;
char digit;
byte nibble;
byte[] bytes;
byte[] newBytes; if ( identifier == null )
throw new IllegalArgumentException( "Argument identifier is null" );
if ( prefix == null )
throw new IllegalArgumentException( "Argument prefix is null" );
if ( ! identifier.startsWith( prefix ) )
throw new InvalidIDException( Messages.format( "tyrex.util.idInvalidPrefix",
prefix, identifier ) );
index = 0;
bytes = new byte[ ( identifier.length() - prefix.length() ) / 2 ];
for ( int i = prefix.length() ; i < identifier.length() ; ++i ) {
digit = identifier.charAt( i );
if ( digit == '-' )
continue;
if ( digit >= '0' && digit <= '9' )
nibble = (byte) ( ( digit - '0' ) << 4 );
else if ( digit >= 'A' && digit <= 'F' )
nibble = (byte) ( ( digit - ( 'A' - 0x0A ) ) << 4 );
else if ( digit >= 'a' && digit <= 'f' )
nibble = (byte) ( ( digit - ( 'a' - 0x0A ) ) << 4 );
else
throw new InvalidIDException( Messages.format( "tyrex.util.idInvalidCharacter",
String.valueOf( digit ), identifier ) );
++i;
if ( i == identifier.length() )
throw new InvalidIDException( Messages.format( "tyrex.util.idInvalidOddDigits",
identifier ) );
digit = identifier.charAt( i );
if ( digit >= '0' && digit <= '9' )
nibble = (byte) ( nibble | ( digit - '0' ) );
else if ( digit >= 'A' && digit <= 'F' )
nibble = (byte) ( nibble | ( digit - ( 'A' - 0x0A ) ) );
else if ( digit >= 'a' && digit <= 'f' )
nibble = (byte) ( nibble | ( digit - ( 'a' - 0x0A ) ) );
else
throw new InvalidIDException( Messages.format( "tyrex.util.idInvalidCharacter",
String.valueOf( digit ), identifier ) );
bytes[ index ] = nibble;
++index;
}
if ( index == bytes.length )
return bytes;
newBytes = new byte[ index ];
while ( index-- > 0 )
newBytes[ index ] = bytes[ index ];
return newBytes;
}
不如把email留下来我明天给你发过去