1 package com.foxinmy.weixin4j.util;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.net.NetworkInterface;
20 import java.nio.ByteBuffer;
21 import java.util.Date;
22 import java.util.Enumeration;
23 import java.util.Random;
24 import java.util.concurrent.atomic.AtomicInteger;
25 import java.util.logging.Level;
26 import java.util.logging.Logger;
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 public class ObjectId implements Comparable<ObjectId>, java.io.Serializable {
67
68 private static final long serialVersionUID = -4415279469780082174L;
69
70 static final Logger LOGGER = Logger.getLogger("org.bson.ObjectId");
71
72
73
74
75
76
77 public static ObjectId get() {
78 return new ObjectId();
79 }
80
81
82
83
84
85
86
87
88
89
90 public static boolean isValid(String s) {
91 if (s == null)
92 return false;
93
94 final int len = s.length();
95 if (len != 24)
96 return false;
97
98 for (int i = 0; i < len; i++) {
99 char c = s.charAt(i);
100 if (c >= '0' && c <= '9')
101 continue;
102 if (c >= 'a' && c <= 'f')
103 continue;
104 if (c >= 'A' && c <= 'F')
105 continue;
106
107 return false;
108 }
109
110 return true;
111 }
112
113
114
115
116
117
118
119 public ObjectId(byte[] b) {
120 if (b.length != 12)
121 throw new IllegalArgumentException("need 12 bytes");
122 ByteBuffer bb = ByteBuffer.wrap(b);
123 _time = bb.getInt();
124 _machine = bb.getInt();
125 _inc = bb.getInt();
126 _new = false;
127 }
128
129
130
131
132 public ObjectId() {
133 _time = (int) (System.currentTimeMillis() / 1000);
134 _machine = _genmachine;
135 _inc = _nextInc.getAndIncrement();
136 _new = true;
137 }
138
139 @Override
140 public int hashCode() {
141 int x = _time;
142 x += (_machine * 111);
143 x += (_inc * 17);
144 return x;
145 }
146
147 @Override
148 public boolean equals(Object o) {
149 if (this == o)
150 return true;
151 if (!(o instanceof ObjectId)) {
152 return false;
153 }
154 ObjectId other = (ObjectId) o;
155 return _time == other._time && _machine == other._machine
156 && _inc == other._inc;
157 }
158
159
160
161
162
163
164 public String toHexString() {
165 final StringBuilder buf = new StringBuilder(24);
166
167 for (final byte b : toByteArray()) {
168 buf.append(String.format("%02x", b & 0xff));
169 }
170
171 return buf.toString();
172 }
173
174
175
176
177
178
179
180 public byte[] toByteArray() {
181 byte b[] = new byte[12];
182 ByteBuffer bb = ByteBuffer.wrap(b);
183
184 bb.putInt(_time);
185 bb.putInt(_machine);
186 bb.putInt(_inc);
187 return b;
188 }
189
190 static String _pos(String s, int p) {
191 return s.substring(p * 2, (p * 2) + 2);
192 }
193
194 public String toString() {
195 byte b[] = toByteArray();
196
197 StringBuilder buf = new StringBuilder(24);
198
199 for (int i = 0; i < b.length; i++) {
200 int x = b[i] & 0xFF;
201 String s = Integer.toHexString(x);
202 if (s.length() == 1)
203 buf.append("0");
204 buf.append(s);
205 }
206
207 return buf.toString();
208 }
209
210 int _compareUnsigned(int i, int j) {
211 long li = 0xFFFFFFFFL;
212 li = i & li;
213 long lj = 0xFFFFFFFFL;
214 lj = j & lj;
215 long diff = li - lj;
216 if (diff < Integer.MIN_VALUE)
217 return Integer.MIN_VALUE;
218 if (diff > Integer.MAX_VALUE)
219 return Integer.MAX_VALUE;
220 return (int) diff;
221 }
222
223 public int compareTo(ObjectId id) {
224 if (id == null)
225 return -1;
226
227 int x = _compareUnsigned(_time, id._time);
228 if (x != 0)
229 return x;
230
231 x = _compareUnsigned(_machine, id._machine);
232 if (x != 0)
233 return x;
234
235 return _compareUnsigned(_inc, id._inc);
236 }
237
238
239
240
241
242
243 public int getTimestamp() {
244 return _time;
245 }
246
247
248
249
250
251
252 public Date getDate() {
253 return new Date(_time * 1000L);
254 }
255
256
257
258
259
260
261 public static int getCurrentCounter() {
262 return _nextInc.get();
263 }
264
265 final int _time;
266 final int _machine;
267 final int _inc;
268
269 boolean _new;
270
271 private static AtomicInteger _nextInc = new AtomicInteger(
272 (new java.util.Random()).nextInt());
273
274 private static final int _genmachine;
275 static {
276 try {
277
278 int machinePiece;
279 {
280 try {
281 StringBuilder sb = new StringBuilder();
282 Enumeration<NetworkInterface> e = NetworkInterface
283 .getNetworkInterfaces();
284 while (e.hasMoreElements()) {
285 NetworkInterface ni = e.nextElement();
286 sb.append(ni.toString());
287 }
288 machinePiece = sb.toString().hashCode() << 16;
289 } catch (Throwable e) {
290
291 LOGGER.log(Level.WARNING, e.getMessage(), e);
292 machinePiece = (new Random().nextInt()) << 16;
293 }
294 LOGGER.fine("machine piece post: "
295 + Integer.toHexString(machinePiece));
296 }
297
298
299
300
301
302 final int processPiece;
303 {
304 int processId = new java.util.Random().nextInt();
305 try {
306 processId = java.lang.management.ManagementFactory
307 .getRuntimeMXBean().getName().hashCode();
308 } catch (Throwable t) {
309 }
310
311 ClassLoader loader = ObjectId.class.getClassLoader();
312 int loaderId = loader != null ? System.identityHashCode(loader)
313 : 0;
314
315 StringBuilder sb = new StringBuilder();
316 sb.append(Integer.toHexString(processId));
317 sb.append(Integer.toHexString(loaderId));
318 processPiece = sb.toString().hashCode() & 0xFFFF;
319 LOGGER.fine("process piece: "
320 + Integer.toHexString(processPiece));
321 }
322
323 _genmachine = machinePiece | processPiece;
324 LOGGER.fine("machine : " + Integer.toHexString(_genmachine));
325 } catch (Exception e) {
326 throw new RuntimeException(e);
327 }
328
329 }
330 }