< prev index next >

src/java.base/share/classes/java/util/UUID.java

Print this page
rev 58210 : 8196334: Optimize UUID#fromString
Reviewed-by: TBD
Contributed-by: plokhotnyuk@gmail.com, jon.chambers@gmail.com, claes.redestad@oracle.com


 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         }


< prev index next >