• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 package com.android.networkrecommendation.scoring.util;
17 
18 import android.util.Base64;
19 import java.security.MessageDigest;
20 import java.security.NoSuchAlgorithmException;
21 
22 /** Hashcode and encoding utils. */
23 public final class HashUtil {
HashUtil()24     private HashUtil() {}
25 
26     /**
27      * Returns a base64-encoded secure hash (using the SHA-256 algorithm) of the provided input.
28      *
29      * @param input the bytes for which the secure hash should be computed.
30      * @return the hash
31      */
secureHash(String input)32     public static String secureHash(String input) {
33         return encodeBase64(getHash(input, "SHA-256"));
34     }
35 
encodeBase64(byte[] input)36     public static String encodeBase64(byte[] input) {
37         return Base64.encodeToString(input, Base64.URL_SAFE | Base64.NO_PADDING | Base64.NO_WRAP);
38     }
39 
40     /** Retrieves the message digest instance for a given hash algorithm. */
getMessageDigest(String hashAlgorithm)41     public static MessageDigest getMessageDigest(String hashAlgorithm) {
42         try {
43             return MessageDigest.getInstance(hashAlgorithm);
44         } catch (NoSuchAlgorithmException e) {
45             return null;
46         }
47     }
48 
49     /**
50      * @return hash of input using hashAlgorithm, or 0-length byte array if input is null, or null
51      *     if hashAlgorithm can't be loaded
52      */
getHash(String input, String hashAlgorithm)53     public static byte[] getHash(String input, String hashAlgorithm) {
54         if (input != null) {
55             MessageDigest digest = getMessageDigest(hashAlgorithm);
56             if (digest == null) {
57                 return null;
58             }
59             return digest.digest(input.getBytes());
60         }
61         return new byte[0];
62     }
63 
64     /**
65      * Gets an SSID-specific hash which also ensures the SSID is in cannonical form (stripped of
66      * quotes).
67      */
getSsidHash(String ssid)68     public static String getSsidHash(String ssid) {
69         return secureHash(NetworkUtil.canonicalizeSsid(ssid));
70     }
71 
72     /** Gets a single hash of over the combined SSID and BSSID. */
getSsidBssidHash(String ssid, String bssid)73     public static String getSsidBssidHash(String ssid, String bssid) {
74         String canonicalSsid = NetworkUtil.canonicalizeSsid(ssid);
75         return secureHash(canonicalSsid + bssid);
76     }
77 
78     /** Return the first 8 bytes of the SHA-256 hash of the given ssid as a long value. */
hashAsLong(String ssid)79     public static long hashAsLong(String ssid) {
80         byte[] h = getHash(ssid, "SHA-256");
81         if (h == null || h.length < 8) {
82             return 0;
83         }
84         return (h[0] & 0xFFL) << 56
85                 | (h[1] & 0xFFL) << 48
86                 | (h[2] & 0xFFL) << 40
87                 | (h[3] & 0xFFL) << 32
88                 | (h[4] & 0xFFL) << 24
89                 | (h[5] & 0xFFL) << 16
90                 | (h[6] & 0xFFL) << 8
91                 | (h[7] & 0xFFL);
92     }
93 }
94