163 * @param name
164 * A byte array to be used to construct a {@code UUID}
165 *
166 * @return A {@code UUID} generated from the specified array
167 */
168 public static UUID nameUUIDFromBytes(byte[] name) {
169 MessageDigest md;
170 try {
171 md = MessageDigest.getInstance("MD5");
172 } catch (NoSuchAlgorithmException nsae) {
173 throw new InternalError("MD5 not supported", nsae);
174 }
175 byte[] md5Bytes = md.digest(name);
176 md5Bytes[6] &= 0x0f; /* clear version */
177 md5Bytes[6] |= 0x30; /* set to version 3 */
178 md5Bytes[8] &= 0x3f; /* clear variant */
179 md5Bytes[8] |= 0x80; /* set to IETF variant */
180 return new UUID(md5Bytes);
181 }
182
183 /**
184 * Creates a {@code UUID} from the string standard representation as
185 * described in the {@link #toString} method.
186 *
187 * @param name
188 * A string that specifies a {@code UUID}
189 *
190 * @return A {@code UUID} with the specified value
191 *
192 * @throws IllegalArgumentException
193 * If name does not conform to the string representation as
194 * described in {@link #toString}
195 *
196 */
197 public static UUID fromString(String name) {
198 int len = name.length();
199 if (len > 36) {
200 throw new IllegalArgumentException("UUID string too large");
201 }
202
203 int dash1 = name.indexOf('-', 0);
204 int dash2 = name.indexOf('-', dash1 + 1);
205 int dash3 = name.indexOf('-', dash2 + 1);
206 int dash4 = name.indexOf('-', dash3 + 1);
207 int dash5 = name.indexOf('-', dash4 + 1);
208
209 // For any valid input, dash1 through dash4 will be positive and dash5
210 // negative, but it's enough to check dash4 and dash5:
211 // - if dash1 is -1, dash4 will be -1
212 // - if dash1 is positive but dash2 is -1, dash4 will be -1
213 // - if dash1 and dash2 is positive, dash3 will be -1, dash4 will be
214 // positive, but so will dash5
215 if (dash4 < 0 || dash5 >= 0) {
216 throw new IllegalArgumentException("Invalid UUID string: " + name);
217 }
|
163 * @param name
164 * A byte array to be used to construct a {@code UUID}
165 *
166 * @return A {@code UUID} generated from the specified array
167 */
168 public static UUID nameUUIDFromBytes(byte[] name) {
169 MessageDigest md;
170 try {
171 md = MessageDigest.getInstance("MD5");
172 } catch (NoSuchAlgorithmException nsae) {
173 throw new InternalError("MD5 not supported", nsae);
174 }
175 byte[] md5Bytes = md.digest(name);
176 md5Bytes[6] &= 0x0f; /* clear version */
177 md5Bytes[6] |= 0x30; /* set to version 3 */
178 md5Bytes[8] &= 0x3f; /* clear variant */
179 md5Bytes[8] |= 0x80; /* set to IETF variant */
180 return new UUID(md5Bytes);
181 }
182
183 private static final byte[] NIBBLES;
184 static {
185 byte[] ns = new byte[256];
186 Arrays.fill(ns, (byte) -1);
187 ns['0'] = 0;
188 ns['1'] = 1;
189 ns['2'] = 2;
190 ns['3'] = 3;
191 ns['4'] = 4;
192 ns['5'] = 5;
193 ns['6'] = 6;
194 ns['7'] = 7;
195 ns['8'] = 8;
196 ns['9'] = 9;
197 ns['A'] = 10;
198 ns['B'] = 11;
199 ns['C'] = 12;
200 ns['D'] = 13;
201 ns['E'] = 14;
202 ns['F'] = 15;
203 ns['a'] = 10;
204 ns['b'] = 11;
205 ns['c'] = 12;
206 ns['d'] = 13;
207 ns['e'] = 14;
208 ns['f'] = 15;
209 NIBBLES = ns;
210 }
211
212 private static long parse4Nibbles(String name, int pos) {
213 byte[] ns = NIBBLES;
214 char ch1 = name.charAt(pos);
215 char ch2 = name.charAt(pos + 1);
216 char ch3 = name.charAt(pos + 2);
217 char ch4 = name.charAt(pos + 3);
218 return (ch1 | ch2 | ch3 | ch4) > 0xff ?
219 -1 : ns[ch1] << 12 | ns[ch2] << 8 | ns[ch3] << 4 | ns[ch4];
220 }
221
222 /**
223 * Creates a {@code UUID} from the string standard representation as
224 * described in the {@link #toString} method.
225 *
226 * @param name
227 * A string that specifies a {@code UUID}
228 *
229 * @return A {@code UUID} with the specified value
230 *
231 * @throws IllegalArgumentException
232 * If name does not conform to the string representation as
233 * described in {@link #toString}
234 *
235 */
236 public static UUID fromString(String name) {
237 if (name.length() == 36) {
238 char ch1 = name.charAt(8);
239 char ch2 = name.charAt(13);
240 char ch3 = name.charAt(18);
241 char ch4 = name.charAt(23);
242 if (ch1 == '-' && ch2 == '-' && ch3 == '-' && ch4 == '-') {
243 long msb1 = parse4Nibbles(name, 0);
244 long msb2 = parse4Nibbles(name, 4);
245 long msb3 = parse4Nibbles(name, 9);
246 long msb4 = parse4Nibbles(name, 14);
247 long lsb1 = parse4Nibbles(name, 19);
248 long lsb2 = parse4Nibbles(name, 24);
249 long lsb3 = parse4Nibbles(name, 28);
250 long lsb4 = parse4Nibbles(name, 32);
251 if ((msb1 | msb2 | msb3 | msb4 | lsb1 | lsb2 | lsb3 | lsb4) >= 0) {
252 return new UUID(
253 msb1 << 48 | msb2 << 32 | msb3 << 16 | msb4,
254 lsb1 << 48 | lsb2 << 32 | lsb3 << 16 | lsb4);
255 }
256 }
257 }
258 return fromString1(name);
259 }
260
261 private static UUID fromString1(String name) {
262 int len = name.length();
263 if (len > 36) {
264 throw new IllegalArgumentException("UUID string too large");
265 }
266
267 int dash1 = name.indexOf('-', 0);
268 int dash2 = name.indexOf('-', dash1 + 1);
269 int dash3 = name.indexOf('-', dash2 + 1);
270 int dash4 = name.indexOf('-', dash3 + 1);
271 int dash5 = name.indexOf('-', dash4 + 1);
272
273 // For any valid input, dash1 through dash4 will be positive and dash5
274 // negative, but it's enough to check dash4 and dash5:
275 // - if dash1 is -1, dash4 will be -1
276 // - if dash1 is positive but dash2 is -1, dash4 will be -1
277 // - if dash1 and dash2 is positive, dash3 will be -1, dash4 will be
278 // positive, but so will dash5
279 if (dash4 < 0 || dash5 >= 0) {
280 throw new IllegalArgumentException("Invalid UUID string: " + name);
281 }
|