• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "uuid.h"
17 
18 #include <algorithm>
19 #include <climits>
20 #include <iomanip>
21 #include <iostream>
22 
23 #include <sys/time.h>
24 
25 namespace OHOS {
26 namespace MMI {
27 namespace {
28 constexpr int32_t UUID_TIME_LOW_FIRST_BYTE = 0;
29 constexpr int32_t UUID_TIME_LOW_SECOND_BYTE = 1;
30 constexpr int32_t UUID_TIME_LOW_THIRD_BYTE = 2;
31 constexpr int32_t UUID_TIME_LOW_FOURTH_BYTE = 3;
32 constexpr int32_t UUID_TIME_MID_FIRST_BYTE = 4;
33 constexpr int32_t UUID_TIME_MID_SECOND_BYTE = 5;
34 constexpr int32_t UUID_VERSION = 6;
35 constexpr int32_t UUID_TIME_HIGH = 7;
36 constexpr int32_t UUID_VARIANT = 8;
37 constexpr int32_t UUID_CLOCK_SEQ = 9;
38 constexpr int32_t UUID_NODE_FIRST_BYTE = 10;
39 constexpr int32_t UUID_NODE_THIRD_BYTE = 12;
40 constexpr int32_t UUID_NODE_FOURTH_BYTE = 13;
41 constexpr int32_t UUID_NODE_FIFTH_BYTE = 14;
42 constexpr int32_t UUID_NODE_SIXTH_BYTE = 15;
43 
44 constexpr int32_t BASE_BIT_OPT_SIZE = 8;
45 constexpr int32_t BIT_OPT_TWO_BYTE = 2;
46 constexpr int32_t BIT_OPT_THREE_BYTE = 3;
47 constexpr int32_t BIT_OPT_FOUR_BYTE = 4;
48 constexpr int32_t BIT_OPT_FIVE_BYTE = 5;
49 constexpr int32_t BIT_OPT_SIX_BYTE = 6;
50 constexpr int32_t BIT_OPT_SEVEN_BYTE = 7;
51 } // namespace
52 
Uuid()53 Uuid::Uuid()
54 {
55     struct timeval tv;
56     struct timezone tz;
57     struct tm randomTime;
58     uint32_t randNum = 0;
59 
60     rand_r(&randNum);
61     gettimeofday(&tv, &tz);
62     localtime_r(&tv.tv_sec, &randomTime);
63 
64     unsigned long int tvUsec = 0;
65     tvUsec = (unsigned long int)tv.tv_usec;
66 
67     uuid_[UUID_NODE_SIXTH_BYTE] =
68         static_cast<uint8_t>(tvUsec & 0x00000000000000FF);
69     uuid_[UUID_NODE_FIFTH_BYTE] =
70         static_cast<uint8_t>((tvUsec & 0x000000000000FF00) >> BASE_BIT_OPT_SIZE);
71     uuid_[UUID_NODE_FOURTH_BYTE] =
72         static_cast<uint8_t>((tvUsec & 0x0000000000FF0000) >> BIT_OPT_TWO_BYTE * BASE_BIT_OPT_SIZE);
73     uuid_[UUID_NODE_THIRD_BYTE] =
74         static_cast<uint8_t>((tvUsec & 0x00000000FF000000) >> BIT_OPT_THREE_BYTE * BASE_BIT_OPT_SIZE);
75     uuid_[UUID_NODE_FIRST_BYTE] =
76         static_cast<uint8_t>((tvUsec & 0x000000FF00000000) >> BIT_OPT_FOUR_BYTE * BASE_BIT_OPT_SIZE);
77     uuid_[UUID_CLOCK_SEQ] =
78         static_cast<uint8_t>((tvUsec & 0x0000FF0000000000) >> BIT_OPT_FIVE_BYTE * BASE_BIT_OPT_SIZE);
79     uuid_[UUID_VARIANT] =
80         static_cast<uint8_t>((tvUsec & 0x00FF000000000000) >> BIT_OPT_SIX_BYTE * BASE_BIT_OPT_SIZE);
81     uuid_[UUID_TIME_HIGH] =
82         static_cast<uint8_t>((tvUsec & 0xFF00000000000000) >> BIT_OPT_SEVEN_BYTE * BASE_BIT_OPT_SIZE);
83     // 4 - 6
84     uuid_[UUID_VERSION] =
85         static_cast<uint8_t>((static_cast<uint32_t>(randomTime.tm_sec) + randNum) & 0xFF);
86     uuid_[UUID_TIME_MID_SECOND_BYTE] =
87         static_cast<uint8_t>((static_cast<uint32_t>(randomTime.tm_min) + (randNum >> BASE_BIT_OPT_SIZE)) & 0xFF);
88     uuid_[UUID_TIME_MID_FIRST_BYTE] = static_cast<uint8_t>((static_cast<uint32_t>(randomTime.tm_hour) +
89                                       (randNum >> BIT_OPT_TWO_BYTE * BASE_BIT_OPT_SIZE)) & 0xFF);
90     // 0 - 3
91     uuid_[UUID_TIME_LOW_FOURTH_BYTE] = static_cast<uint8_t>((static_cast<uint32_t>(randomTime.tm_mday) +
92                                        (randNum >> BIT_OPT_THREE_BYTE * BASE_BIT_OPT_SIZE)) & 0xFF);
93     uuid_[UUID_TIME_LOW_THIRD_BYTE] =
94         static_cast<uint8_t>(static_cast<uint32_t>(randomTime.tm_mon) & 0xFF);
95     uuid_[UUID_TIME_LOW_SECOND_BYTE] =
96         static_cast<uint8_t>(static_cast<uint32_t>(randomTime.tm_year) & 0xFF);
97     uuid_[UUID_TIME_LOW_FIRST_BYTE] =
98         static_cast<uint8_t>((static_cast<uint32_t>(randomTime.tm_year) & 0xFF00) >> BASE_BIT_OPT_SIZE);
99 }
100 
ConvertToHex(uint8_t c)101 char ConvertToHex(uint8_t c)
102 {
103     if (c < 0xa) {
104         return static_cast<char>(c + '0');
105     } else if (c >= 0xa && c <= 0xf) {
106         return static_cast<char>(c - 0xa + 'a');
107     }
108 
109     return '0';
110 }
111 
ConvertToStdString(std::string & s) const112 void Uuid::ConvertToStdString(std::string& s) const
113 {
114     static constexpr int32_t uuidBufMaxSize = 37;
115     char uuidBuf[uuidBufMaxSize + 1] = {0};
116     int32_t writePos = 0;
117     for (size_t i = 0; i < UUID128_BYTES_TYPE; i++) {
118         const uint8_t c = uuid_[i];
119         const uint8_t low4Bit = (c & 0xf);
120         const uint8_t high4Bit = ((c >> 4) & 0xf);
121         if (writePos <= uuidBufMaxSize) {
122             uuidBuf[writePos++] = ConvertToHex(low4Bit);
123             uuidBuf[writePos++] = ConvertToHex(high4Bit);
124             if (i == 3 || i == 5 || i == 7 || i == 9) { // 3 5 7 9 uuid 按标准格式(8-4-4-4-12)分隔符
125                 uuidBuf[writePos++] = '-';
126             }
127         }
128     }
129     uuidBuf[uuidBufMaxSize - 1] = '\0';
130     s = uuidBuf;
131 }
132 } // namespace MMI
133 } // namespace OHOS
134