java生成唯一ID,相对唯一(15位和32位)的简单实现

星期三, 2012-08-08 | Author: Lee | algorithm-learn, JAVA-and-J2EE | 6,817 views

好久没有写文章了,在oschina上看到的,感觉挺不错,摘录代码如下:
实际上更多的是根据自己的需求去实现一种不重复的主键,这里只要提供思路,以供借鉴之用.
32位生成方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package com.i5a6.uuid;
 
import java.io.Serializable;
import java.net.InetAddress;
import java.util.Properties;
import java.util.UUID;
 
/**
 * @author lee
 * 
 * 根据IP地址,JVM虚拟机,时间,同步序列号的情况下产生的相对唯一ID,可用于多线程,多服务器。
 * 32位 系统的 UUID 生成为36位
 */
public class UUIDHexGenerator extends AbstractUUIDGenerator {
	public static final UUIDHexGenerator DEFAULT = new UUIDHexGenerator();
	private String sep = "";
 
	protected String format(final int intval) {
		final String formatted = Integer.toHexString(intval);
		final StringBuffer buf = new StringBuffer("00000000");
		buf.replace(8 - formatted.length(), 8, formatted);
		return buf.toString();
	}
 
	protected String format(final short shortval) {
		final String formatted = Integer.toHexString(shortval);
		final StringBuffer buf = new StringBuffer("0000");
		buf.replace(4 - formatted.length(), 4, formatted);
		return buf.toString();
	}
 
	public Serializable generate(final Object obj) {
		return new StringBuffer(36).append(format(getIP())).append(sep)
				.append(format(getJVM())).append(sep)
				.append(format(getHiTime())).append(sep)
				.append(format(getLoTime())).append(sep)
				.append(format(getCount())).toString();
	}
 
	public void configure(final Properties params) {
		sep = params.getProperty("separator", "");
	}
 
	public static final String generator() {
		return String.valueOf(UUIDHexGenerator.DEFAULT.generate(null));
	}
 
	public static final String generator(final Object obj) {
		return String.valueOf(UUIDHexGenerator.DEFAULT.generate(obj));
	}
 
	public static void main(final String[] args) {
		String s=UUIDHexGenerator.generator();
		System.out.println(s.length());
		System.out.println(UUIDHexGenerator.generator());
		System.out.println(UUIDHexGenerator.generator());
		String s2=UUID.randomUUID().toString();
		System.out.println(s2);
		System.out.println(s2.length());
	}
}
 
abstract class AbstractUUIDGenerator {
 
	private static final int IP;
	static {
		int ipadd;
		try {
			ipadd = toInt(InetAddress.getLocalHost().getAddress());
		} catch (final Exception e) {
			ipadd = 0;
		}
		IP = ipadd;
	}
 
	public static int toInt(final byte[] bytes) {
		int result = 0;
		for (int i = 0; i < 4; i++) {
			result = (result << 8) - Byte.MIN_VALUE + bytes[i];
		}
		return result;
	}
 
	private static short counter = (short) 0;
	private static final int JVM = (int) (System.currentTimeMillis() >>> 8);
 
	public AbstractUUIDGenerator() {
	}
 
	/**
	 * Unique across JVMs on this machine (unless they load this class in the
	 * same quater second - very unlikely)
	 */
	protected int getJVM() {
		return JVM;
	}
 
	/**
	 * Unique in a millisecond for this JVM instance (unless there are >
	 * Short.MAX_VALUE instances created in a millisecond)
	 */
	protected short getCount() {
		synchronized (AbstractUUIDGenerator.class) {
			if (counter < 0)
				counter = 0;
			return counter++;
		}
	}
 
	/**
	 * Unique in a local network
	 */
	protected int getIP() {
		return IP;
	}
 
	/**
	 * Unique down to millisecond
	 */
	protected short getHiTime() {
		return (short) (System.currentTimeMillis() >>> 32);
	}
 
	protected int getLoTime() {
		return (int) System.currentTimeMillis();
	}
}

15位生成方式,不支持多系统同时运行,单独系统可以生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package com.i5a6.uuid;
 
/**
 * @author lee
 * 
 */
public class UUIDMaker {
 
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		for (int i = 0; i < 100; i++) {
			String s = generate();
			System.out.println(s);
		}
 
	}
 
	private final static String str = "1234567890abcdefghijklmnopqrstuvwxyz";
 
	private final static int pixLen = str.length();
 
	private static volatile int pixOne = 0;
 
	private static volatile int pixTwo = 0;
 
	private static volatile int pixThree = 0;
 
	private static volatile int pixFour = 0;
 
	/**
	 * 
	 * 生成短时间内不会重复的长度为15位的字符串,主要用于***模块数据库主键生成使用。<br/>
	 * 
	 * 生成策略为获取自1970年1月1日零时零分零秒至当前时间的毫秒数的16进制字符串值,该字符串值为11位<br/>
	 * 
	 * 并追加四位"0-z"的自增字符串.<br/>
	 * 
	 * 如果系统时间设置为大于<b>2304-6-27 7:00:26<b/>的时间,将会报错!<br/>
	 * 
	 * 由于系统返回的毫秒数与操作系统关系很大,所以本方法并不准确。本方法可以保证在系统返回的一个毫秒数内生成36的4次方个(1679616)ID不重复。<br/>
	 * 
	 */
 
	final public synchronized static String generate() {
 
		String hexString = Long.toHexString(System.currentTimeMillis());
 
		pixFour++;
 
		if (pixFour == pixLen) {
 
			pixFour = 0;
 
			pixThree++;
 
			if (pixThree == pixLen) {
 
				pixThree = 0;
 
				pixTwo++;
 
				if (pixTwo == pixLen) {
 
					pixTwo = 0;
 
					pixOne++;
 
					if (pixOne == pixLen) {
 
						pixOne = 0;
					}
 
				}
 
			}
 
		}
		return hexString + str.charAt(pixOne) + str.charAt(pixTwo)
				+ str.charAt(pixThree) + str.charAt(pixFour);
	}
 
}

Tags: , ,

文章作者: Lee

本文地址: http://blog.i5a6.com/1000.html

除非注明,I5A6文章均为原创,转载请以链接形式标明本文地址

No comments yet.

Leave a comment

Rss

Search

文章分类

Meta