UUID.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/core/utils/UUID.h>
  6. #include <aws/core/utils/HashingUtils.h>
  7. #include <aws/core/utils/StringUtils.h>
  8. #include <aws/core/utils/crypto/Factories.h>
  9. #include <aws/core/utils/crypto/SecureRandom.h>
  10. #include <iomanip>
  11. namespace Aws
  12. {
  13. namespace Utils
  14. {
  15. static const size_t UUID_STR_SIZE = 0x24u; // 36 characters
  16. static const size_t VERSION_LOCATION = 0x06u;
  17. static const size_t VARIANT_LOCATION = 0x08u;
  18. static const unsigned char VERSION = 0x40u;
  19. static const unsigned char VERSION_MASK = 0x0Fu;
  20. static const unsigned char VARIANT = 0x80u;
  21. static const unsigned char VARIANT_MASK = 0x3Fu;
  22. static void hexify(Aws::String& ss, const unsigned char* toWrite, size_t min, size_t max)
  23. {
  24. for (size_t i = min; i < max; ++i)
  25. {
  26. ss.push_back("0123456789ABCDEF"[toWrite[i] >> 4]);
  27. ss.push_back("0123456789ABCDEF"[toWrite[i] & 0x0F]);
  28. }
  29. }
  30. UUID::UUID(const Aws::String& uuidToConvert)
  31. {
  32. //GUID has 2 characters per byte + 4 dashes = 36 bytes
  33. assert(uuidToConvert.length() == UUID_STR_SIZE);
  34. memset(m_uuid, 0, sizeof(m_uuid));
  35. Aws::String escapedHexStr(uuidToConvert);
  36. StringUtils::Replace(escapedHexStr, "-", "");
  37. assert(escapedHexStr.length() == UUID_BINARY_SIZE * 2);
  38. ByteBuffer&& rawUuid = HashingUtils::HexDecode(escapedHexStr);
  39. memcpy(m_uuid, rawUuid.GetUnderlyingData(), rawUuid.GetLength());
  40. }
  41. UUID::UUID(const unsigned char toCopy[UUID_BINARY_SIZE])
  42. {
  43. memcpy(m_uuid, toCopy, sizeof(m_uuid));
  44. }
  45. UUID::operator Aws::String() const
  46. {
  47. Aws::String ss;
  48. ss.reserve(UUID_STR_SIZE);
  49. hexify(ss, m_uuid, 0, 4);
  50. ss.push_back('-');
  51. hexify(ss, m_uuid, 4, 6);
  52. ss.push_back('-');
  53. hexify(ss, m_uuid, 6, 8);
  54. ss.push_back('-');
  55. hexify(ss, m_uuid, 8, 10);
  56. ss.push_back('-');
  57. hexify(ss, m_uuid, 10, 16);
  58. return ss;
  59. }
  60. UUID UUID::RandomUUID()
  61. {
  62. auto secureRandom = Crypto::CreateSecureRandomBytesImplementation();
  63. assert(secureRandom);
  64. unsigned char randomBytes[UUID_BINARY_SIZE];
  65. memset(randomBytes, 0, UUID_BINARY_SIZE);
  66. secureRandom->GetBytes(randomBytes, UUID_BINARY_SIZE);
  67. //Set version bits to 0100
  68. //https://tools.ietf.org/html/rfc4122#section-4.1.3
  69. randomBytes[VERSION_LOCATION] = (randomBytes[VERSION_LOCATION] & VERSION_MASK) | VERSION;
  70. //set variant bits to 10
  71. //https://tools.ietf.org/html/rfc4122#section-4.1.1
  72. randomBytes[VARIANT_LOCATION] = (randomBytes[VARIANT_LOCATION] & VARIANT_MASK) | VARIANT;
  73. return UUID(randomBytes);
  74. }
  75. }
  76. }