4 Copyright (c) 2014 Graeme Hill (http://graemehill.ca)
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 #include <uuid/uuid.h>
32 #include <CoreFoundation/CFUUID.h>
45 // overload << so that it's easy to convert to a string
46 ostream &operator<<(ostream &s, const Guid &guid)
48 return s << hex << setfill('0')
49 << setw(2) << (int)guid._bytes[0]
50 << setw(2) << (int)guid._bytes[1]
51 << setw(2) << (int)guid._bytes[2]
52 << setw(2) << (int)guid._bytes[3]
54 << setw(2) << (int)guid._bytes[4]
55 << setw(2) << (int)guid._bytes[5]
57 << setw(2) << (int)guid._bytes[6]
58 << setw(2) << (int)guid._bytes[7]
60 << setw(2) << (int)guid._bytes[8]
61 << setw(2) << (int)guid._bytes[9]
63 << setw(2) << (int)guid._bytes[10]
64 << setw(2) << (int)guid._bytes[11]
65 << setw(2) << (int)guid._bytes[12]
66 << setw(2) << (int)guid._bytes[13]
67 << setw(2) << (int)guid._bytes[14]
68 << setw(2) << (int)guid._bytes[15];
71 // create a guid from vector of bytes
72 Guid::Guid(const vector<unsigned char> &bytes)
77 // create a guid from array of bytes
78 Guid::Guid(const unsigned char *bytes)
80 _bytes.assign(bytes, bytes + 16);
83 // create a guid from array of words
84 Guid::Guid(const uint16_t *bytes, bool reverse)
87 for (size_t i = 8; i > 0; --i)
89 _bytes.push_back(bytes[i - 1] >> 8);
90 _bytes.push_back(bytes[i - 1] & 0xFF);
93 for (size_t i = 0; i < 8; ++i)
95 _bytes.push_back(bytes[i] & 0xFF);
96 _bytes.push_back(bytes[i] >> 8);
101 // converts a single hex char to a number (0 - 15)
102 static unsigned char hexDigitToChar(char ch)
104 if (ch > 47 && ch < 58)
105 return (unsigned char)(ch - 48);
107 if (ch > 96 && ch < 103)
108 return (unsigned char)(ch - 87);
110 if (ch > 64 && ch < 71)
111 return (unsigned char)(ch - 55);
116 // converts the two hexadecimal characters to an unsigned char (a byte)
117 static unsigned char hexPairToChar(char a, char b)
119 return hexDigitToChar(a) * 16 + hexDigitToChar(b);
122 // create a guid from string
123 Guid::Guid(const string &fromString)
127 char charOne = 0, charTwo;
128 bool lookingForFirstChar = true;
130 for (const char &ch : fromString)
135 if (lookingForFirstChar)
138 lookingForFirstChar = false;
143 auto byte = hexPairToChar(charOne, charTwo);
144 _bytes.push_back(byte);
145 lookingForFirstChar = true;
154 _bytes = vector<unsigned char>(16, 0);
158 Guid::Guid(const Guid &other)
160 _bytes = other._bytes;
163 // overload assignment operator
164 Guid &Guid::operator=(const Guid &other)
166 _bytes = other._bytes;
170 // overload equality operator
171 bool Guid::operator==(const Guid &other) const
173 return _bytes == other._bytes;
176 // overload inequality operator
177 bool Guid::operator!=(const Guid &other) const
179 return !((*this) == other);
182 const std::string Guid::toString() const
184 std::stringstream os;
189 // This is the linux friendly implementation, but it could work on other
190 // systems that have libuuid available
192 Guid GuidGenerator::newGuid()
200 // this is the mac and ios version
202 Guid GuidGenerator::newGuid()
204 auto newId = CFUUIDCreate(NULL);
205 auto bytes = CFUUIDGetUUIDBytes(newId);
208 const unsigned char byteArray[16] =
231 // obviously this is the windows version
233 Guid GuidGenerator::newGuid()
236 CoCreateGuid(&newId);
238 const unsigned char bytes[16] =
240 (newId.Data1 >> 24) & 0xFF,
241 (newId.Data1 >> 16) & 0xFF,
242 (newId.Data1 >> 8) & 0xFF,
243 (newId.Data1) & 0xff,
245 (newId.Data2 >> 8) & 0xFF,
246 (newId.Data2) & 0xff,
248 (newId.Data3 >> 8) & 0xFF,
249 (newId.Data3) & 0xFF,
265 // android version that uses a call to a java api
267 GuidGenerator::GuidGenerator(JNIEnv *env)
270 _uuidClass = env->FindClass("java/util/UUID");
271 _newGuidMethod = env->GetStaticMethodID(_uuidClass, "randomUUID", "()Ljava/util/UUID;");
272 _mostSignificantBitsMethod = env->GetMethodID(_uuidClass, "getMostSignificantBits", "()J");
273 _leastSignificantBitsMethod = env->GetMethodID(_uuidClass, "getLeastSignificantBits", "()J");
276 Guid GuidGenerator::newGuid()
278 jobject javaUuid = _env->CallStaticObjectMethod(_uuidClass, _newGuidMethod);
279 jlong mostSignificant = _env->CallLongMethod(javaUuid, _mostSignificantBitsMethod);
280 jlong leastSignificant = _env->CallLongMethod(javaUuid, _leastSignificantBitsMethod);
282 unsigned char bytes[16] =
284 (mostSignificant >> 56) & 0xFF,
285 (mostSignificant >> 48) & 0xFF,
286 (mostSignificant >> 40) & 0xFF,
287 (mostSignificant >> 32) & 0xFF,
288 (mostSignificant >> 24) & 0xFF,
289 (mostSignificant >> 16) & 0xFF,
290 (mostSignificant >> 8) & 0xFF,
291 (mostSignificant) & 0xFF,
292 (leastSignificant >> 56) & 0xFF,
293 (leastSignificant >> 48) & 0xFF,
294 (leastSignificant >> 40) & 0xFF,
295 (leastSignificant >> 32) & 0xFF,
296 (leastSignificant >> 24) & 0xFF,
297 (leastSignificant >> 16) & 0xFF,
298 (leastSignificant >> 8) & 0xFF,
299 (leastSignificant) & 0xFF,