• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.asuite.clearcut.junit.listener;
18 import java.nio.charset.Charset;
19 import java.security.MessageDigest;
20 import java.security.NoSuchAlgorithmException;
21 import java.util.Objects;
22 import java.util.UUID;
23 
24 public class UUID5 {
25     private static final Charset UTF8 = Charset.forName("UTF-8");
26     public static final UUID NAMESPACE_DNS = UUID.fromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8");
27     public static final UUID NAMESPACE_URL = UUID.fromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
28     public static final UUID NAMESPACE_OID = UUID.fromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8");
29     public static final UUID NAMESPACE_X500 = UUID.fromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8");
30 
uuidOf(UUID namespace, String name)31     public static UUID uuidOf(UUID namespace, String name) {
32         return uuidOf(namespace, Objects.requireNonNull(name, "name == null").getBytes(UTF8));
33     }
34 
uuidOf(UUID namespace, byte[] name)35     public static UUID uuidOf(UUID namespace, byte[] name) {
36         MessageDigest md;
37         try {
38             md = MessageDigest.getInstance("SHA-1");
39         } catch (NoSuchAlgorithmException nsae) {
40             throw new InternalError("SHA-1 not supported");
41         }
42         md.update(toBytes(Objects.requireNonNull(namespace, "namespace is null")));
43         md.update(Objects.requireNonNull(name, "name is null"));
44         byte[] sha1Bytes = md.digest();
45         sha1Bytes[6] &= 0x0f;  /* clear version        */
46         sha1Bytes[6] |= 0x50;  /* set to version 5     */
47         sha1Bytes[8] &= 0x3f;  /* clear variant        */
48         sha1Bytes[8] |= 0x80;  /* set to IETF variant  */
49         return fromBytes(sha1Bytes);
50     }
51 
fromBytes(byte[] data)52     private static UUID fromBytes(byte[] data) {
53         // Based on the private UUID(bytes[]) constructor
54         long msb = 0;
55         long lsb = 0;
56         assert data.length >= 16;
57         for (int i = 0; i < 8; i++)
58             msb = (msb << 8) | (data[i] & 0xff);
59         for (int i = 8; i < 16; i++)
60             lsb = (lsb << 8) | (data[i] & 0xff);
61         return new UUID(msb, lsb);
62     }
63 
toBytes(UUID uuid)64     private static byte[] toBytes(UUID uuid) {
65         // inverted logic of fromBytes()
66         byte[] out = new byte[16];
67         long msb = uuid.getMostSignificantBits();
68         long lsb = uuid.getLeastSignificantBits();
69         for (int i = 0; i < 8; i++)
70             out[i] = (byte) ((msb >> ((7 - i) * 8)) & 0xff);
71         for (int i = 8; i < 16; i++)
72             out[i] = (byte) ((lsb >> ((15 - i) * 8)) & 0xff);
73         return out;
74     }
75 }