hash_util.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "chromecast/base/hash_util.h"
  5. #include <limits.h>
  6. #include <vector>
  7. #include "base/check_op.h"
  8. #include "base/hash/sha1.h"
  9. #include "base/logging.h"
  10. #include "base/notreached.h"
  11. #include "base/stl_util.h"
  12. #include "base/strings/string_number_conversions.h"
  13. #include "base/strings/string_split.h"
  14. #include "base/strings/string_util.h"
  15. #include "chromecast/base/legacy_app_id_mapper.h"
  16. #include "chromecast/base/version.h"
  17. namespace chromecast {
  18. namespace {
  19. const size_t kAppIdV2StrLen = 8;
  20. } // namespace
  21. uint64_t HashToUInt64(const std::string& value) {
  22. uint64_t output;
  23. const std::string sha1hash = base::SHA1HashString(value);
  24. DCHECK_GE(sha1hash.size(), sizeof(output));
  25. memcpy(&output, sha1hash.data(), sizeof(output));
  26. return output;
  27. }
  28. uint32_t HashToUInt32(const std::string& value) {
  29. uint32_t output;
  30. const std::string sha1hash = base::SHA1HashString(value);
  31. DCHECK_GE(sha1hash.size(), sizeof(output));
  32. memcpy(&output, sha1hash.data(), sizeof(output));
  33. return output;
  34. }
  35. uint64_t HashGUID64(const std::string& guid) {
  36. std::string hex;
  37. base::RemoveChars(guid, "-", &hex);
  38. uint64_t output;
  39. DCHECK_EQ(hex.size(), 32u);
  40. if (base::HexStringToUInt64(hex.substr(0, 16), &output))
  41. return output;
  42. NOTREACHED();
  43. return 0;
  44. }
  45. uint32_t HashAppId32(const std::string& app_id) {
  46. uint32_t output;
  47. if (app_id.size() == kAppIdV2StrLen &&
  48. base::HexStringToUInt(app_id, &output)) {
  49. return output;
  50. }
  51. return MapLegacyAppId(app_id);
  52. }
  53. uint64_t HashCastBuildNumber64(const std::string& build_number) {
  54. uint64_t return_value = 0;
  55. std::vector<std::string> tokens(base::SplitString(
  56. build_number, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL));
  57. const size_t tsize = tokens.size();
  58. if (tsize < 1 || tsize > 4)
  59. return static_cast<uint64_t>(-1);
  60. int bits = 64 / tsize;
  61. // special case for 3-tuple to make hex look nicer.
  62. if (tsize == 3)
  63. bits = 16;
  64. for (size_t i = 0; i < tsize; ++i) {
  65. // special case for the last token of 3-tuple.
  66. if (tsize == 3 && i == 2)
  67. bits = 32;
  68. return_value <<= bits;
  69. unsigned value = 0;
  70. if (!base::StringToUint(tokens[i], &value))
  71. return static_cast<uint64_t>(-1);
  72. if (bits != 64) // avoid overflow
  73. value &= (static_cast<uint64_t>(1) << bits) - 1;
  74. return_value |= value;
  75. }
  76. return return_value;
  77. }
  78. uint64_t HashSessionId64(const std::string& session_id) {
  79. return HashGUID64(session_id);
  80. }
  81. uint64_t HashSdkVersion64(const std::string& sdk_version) {
  82. if (sdk_version.empty())
  83. return 0;
  84. // Sdk version is usually in "X.Y.Z(.minor)" format.
  85. // Following code is a little bit relaxed to accept all sub-fields optional.
  86. uint64_t return_value = 0;
  87. std::vector<std::string> tokens(base::SplitString(
  88. sdk_version, ".", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL));
  89. for (size_t i = 0; i < 4; ++i) {
  90. return_value <<= 16;
  91. if (tokens.size() > i) {
  92. unsigned value = 0;
  93. if (base::StringToUint(tokens[i], &value)) {
  94. return_value |= value & 0xFFFF;
  95. } else {
  96. LOG_IF(ERROR, !CAST_IS_DEBUG_BUILD())
  97. << "Sdk version " << sdk_version << " is not in correct format.";
  98. return static_cast<uint64_t>(-1);
  99. }
  100. }
  101. }
  102. return return_value;
  103. }
  104. uint32_t HashSocketId32(const std::string& socket_id) {
  105. uint32_t output;
  106. // socket id is usually just numerical.
  107. if (base::StringToUint(socket_id, &output)) {
  108. return output;
  109. } else { // CastControlSocket and unittests.
  110. return HashToUInt32(socket_id);
  111. }
  112. }
  113. uint32_t HashConnectionId32(const std::string& connection_id) {
  114. return HashToUInt32(connection_id);
  115. }
  116. uint64_t HashAndroidBuildNumber64(const std::string& build_id) {
  117. if (build_id.length() == 0) {
  118. return static_cast<uint64_t>(-1);
  119. }
  120. uint64_t value = 0;
  121. for (const char& c : build_id.substr(0, sizeof(value) / sizeof(char))) {
  122. value <<= CHAR_BIT;
  123. value += c;
  124. }
  125. return value;
  126. }
  127. } // namespace chromecast