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