• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/metrics/metrics_hashes.h"
6 
7 #include <string.h>
8 
9 #include "base/check_op.h"
10 #include "base/hash/md5.h"
11 #include "base/hash/sha1.h"
12 #include "base/sys_byteorder.h"
13 
14 namespace base {
15 namespace {
16 
17 // Converts the 8-byte prefix of an MD5 hash into a uint64_t value.
DigestToUInt64(const base::MD5Digest & digest)18 inline uint64_t DigestToUInt64(const base::MD5Digest& digest) {
19   uint64_t value;
20   DCHECK_GE(sizeof(digest.a), sizeof(value));
21   memcpy(&value, digest.a, sizeof(value));
22   return base::NetToHost64(value);
23 }
24 
25 // Converts the 4-byte prefix of an MD5 hash into a uint32_t value.
DigestToUInt32(const base::MD5Digest & digest)26 inline uint32_t DigestToUInt32(const base::MD5Digest& digest) {
27   uint32_t value;
28   DCHECK_GE(sizeof(digest.a), sizeof(value));
29   memcpy(&value, digest.a, sizeof(value));
30   return base::NetToHost32(value);
31 }
32 
33 }  // namespace
34 
HashMetricName(base::StringPiece name)35 uint64_t HashMetricName(base::StringPiece name) {
36   // Corresponding Python code for quick look up:
37   //
38   //   import struct
39   //   import hashlib
40   //   struct.unpack('>Q', hashlib.md5(name.encode('utf-8')).digest()[:8])[0]
41   //
42   base::MD5Digest digest;
43   base::MD5Sum(name.data(), name.size(), &digest);
44   return DigestToUInt64(digest);
45 }
46 
HashMetricNameAs32Bits(base::StringPiece name)47 uint32_t HashMetricNameAs32Bits(base::StringPiece name) {
48   base::MD5Digest digest;
49   base::MD5Sum(name.data(), name.size(), &digest);
50   return DigestToUInt32(digest);
51 }
52 
HashFieldTrialName(base::StringPiece name)53 uint32_t HashFieldTrialName(base::StringPiece name) {
54   // SHA-1 is designed to produce a uniformly random spread in its output space,
55   // even for nearly-identical inputs.
56   unsigned char sha1_hash[base::kSHA1Length];
57   base::SHA1HashBytes(reinterpret_cast<const unsigned char*>(name.data()),
58                       name.size(), sha1_hash);
59 
60   uint32_t bits;
61   static_assert(sizeof(bits) < sizeof(sha1_hash), "more data required");
62   memcpy(&bits, sha1_hash, sizeof(bits));
63 
64   return base::ByteSwapToLE32(bits);
65 }
66 
67 }  // namespace base
68