1 /*
2  * Copyright (C) 2024 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 #define CONSTANT_ZERO 0
19 #define CONSTANT_FOUR 4
20 #define CONSTANT_EIGHT 8
21 #define CONSTANT_TWELVE 12
22 #define CONSTANT_SIXTEEN 16
23 #define CONSTANT_TWENTY 20
24 
25 namespace OHOS {
26 namespace Bluetooth {
27 const std::regex uuidRegex("^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$");
28 
UUID(const long mostSigBits,const long leastSigBits)29 UUID::UUID(const long mostSigBits, const long leastSigBits)
30 {
31     this->uuid_[15] = static_cast<uint8_t>(leastSigBits & 0x00000000000000FF); // 15是uuid的数组下标
32     this->uuid_[14] = static_cast<uint8_t>((leastSigBits & 0x000000000000FF00) >> 8); // 14是uuid的数组下标,右移8位
33     // 13是uuid的数组下标,右移16位
34     this->uuid_[13] = static_cast<uint8_t>((leastSigBits & 0x0000000000FF0000) >> 16);
35     // 12是uuid的数组下标,右移24位
36     this->uuid_[12] = static_cast<uint8_t>((leastSigBits & 0x00000000FF000000) >> 24);
37     // 11是uuid的数组下标,右移32位
38     this->uuid_[11] = static_cast<uint8_t>((leastSigBits & 0x000000FF00000000) >> 32);
39     // 10是uuid的数组下标,右移40位
40     this->uuid_[10] = static_cast<uint8_t>((leastSigBits & 0x0000FF0000000000) >> 40);
41     this->uuid_[9] = static_cast<uint8_t>((leastSigBits & 0x00FF000000000000) >> 48); // 9是uuid的数组下标,右移48位
42     this->uuid_[8] = static_cast<uint8_t>((leastSigBits & 0xFF00000000000000) >> 56); // 8是uuid的数组下标,右移56位
43     this->uuid_[7] = static_cast<uint8_t>(mostSigBits & 0x00000000000000FF); // 7是uuid的数组下标,右移8位
44     this->uuid_[6] = static_cast<uint8_t>((mostSigBits & 0x000000000000FF00) >> 8); // 6是uuid的数组下标,右移8位
45     this->uuid_[5] = static_cast<uint8_t>((mostSigBits & 0x0000000000FF0000) >> 16); // 5是uuid的数组下标,右移16位
46     this->uuid_[4] = static_cast<uint8_t>((mostSigBits & 0x00000000FF000000) >> 24); // 4是uuid的数组下标,右移24位
47     this->uuid_[3] = static_cast<uint8_t>((mostSigBits & 0x000000FF00000000) >> 32); // 3是uuid的数组下标,右移32位
48     this->uuid_[2] = static_cast<uint8_t>((mostSigBits & 0x0000FF0000000000) >> 40); // 2是uuid的数组下标,右移40位
49     this->uuid_[1] = static_cast<uint8_t>((mostSigBits & 0x00FF000000000000) >> 48); // 1是uuid的数组下标,右移48位
50     this->uuid_[0] = static_cast<uint8_t>((mostSigBits & 0xFF00000000000000) >> 56); // 0是uuid的数组下标,右移56位
51 }
52 
FromString(const std::string & name)53 UUID UUID::FromString(const std::string &name)
54 {
55     UUID ret;
56     std::string tmp = name;
57     std::size_t pos = tmp.find("-");
58 
59     while (pos != std::string::npos) {
60         tmp.replace(pos, 1, "");
61         pos = tmp.find("-");
62     }
63 
64     for (std::size_t i = 0; (i + 1) < tmp.length();) {
65         ret.uuid_[i / 2] = std::stoi(tmp.substr(i, 2), nullptr, 16); // uuid的长度为16,i / 2作为uuid的数组下标
66         i += 2; // for 循环中,每轮增加2
67     }
68 
69     return ret;
70 }
71 
RandomUUID()72 UUID UUID::RandomUUID()
73 {
74     UUID random;
75 
76     struct timeval tv;
77     struct timezone tz;
78     struct tm randomTime;
79     unsigned int randNum = 0;
80 
81     rand_r(&randNum);
82     gettimeofday(&tv, &tz);
83     localtime_r(&tv.tv_sec, &randomTime);
84     random.uuid_[15] = static_cast<uint8_t>(tv.tv_usec & 0x00000000000000FF); // 15是uuid的数组下标
85     random.uuid_[14] = static_cast<uint8_t>((tv.tv_usec & 0x000000000000FF00) >> 8); // 14是uuid的数组下标,右移8位
86     random.uuid_[13] = static_cast<uint8_t>((tv.tv_usec & 0x0000000000FF0000) >> 16); // 13是uuid的数组下标,右移16位
87     random.uuid_[12] = static_cast<uint8_t>((tv.tv_usec & 0x00000000FF000000) >> 24); // 12是uuid的数组下标,右移24位
88     random.uuid_[10] = static_cast<uint8_t>((tv.tv_usec & 0x000000FF00000000) >> 32); // 10是uuid的数组下标,右移32位
89     random.uuid_[9] = static_cast<uint8_t>((tv.tv_usec & 0x0000FF0000000000) >> 40); // 9是uuid的数组下标,右移40位
90     random.uuid_[8] = static_cast<uint8_t>((tv.tv_usec & 0x00FF000000000000) >> 48); // 8是uuid的数组下标,右移48位
91     random.uuid_[7] = static_cast<uint8_t>((tv.tv_usec & 0xFF00000000000000) >> 56); // 7是uuid的数组下标,右移56位
92     // 6是uuid的数组下标
93     random.uuid_[6] = static_cast<uint8_t>((randomTime.tm_sec + static_cast<int>(randNum)) & 0xFF);
94     // 5是uuid的数组下标,右移8位
95     random.uuid_[5] = static_cast<uint8_t>((randomTime.tm_min + (randNum >> 8)) & 0xFF);
96     // 4是uuid的数组下标,右移16位
97     random.uuid_[4] = static_cast<uint8_t>((randomTime.tm_hour + (randNum >> 16)) & 0xFF);
98     // 3是uuid的数组下标,右移24位
99     random.uuid_[3] = static_cast<uint8_t>((randomTime.tm_mday + (randNum >> 24)) & 0xFF);
100     random.uuid_[2] = static_cast<uint8_t>(randomTime.tm_mon & 0xFF); // 2是uuid的数组下标
101     random.uuid_[1] = static_cast<uint8_t>(randomTime.tm_year & 0xFF); // 1是uuid的数组下标
102     random.uuid_[0] = static_cast<uint8_t>((randomTime.tm_year & 0xFF00) >> 8); // 0是uuid的数组下标,右移8位
103     return random;
104 }
105 
ToString() const106 std::string UUID::ToString() const
107 {
108     std::string tmp = "";
109     std::string ret = "";
110     static const char *hex = "0123456789ABCDEF";
111 
112     for (auto it = this->uuid_.begin(); it != this->uuid_.end(); it++) {
113         tmp.push_back(hex[(((*it) >> 4) & 0xF)]); // 右移4位
114         tmp.push_back(hex[(*it) & 0xF]);
115     }
116     // ToString操作,8, 4, 12, 16,20 作为截取字符的开始位置或截取长度
117     ret = tmp.substr(CONSTANT_ZERO, CONSTANT_EIGHT) + "-" +
118             tmp.substr(CONSTANT_EIGHT, CONSTANT_FOUR) + "-" +
119             tmp.substr(CONSTANT_TWELVE, CONSTANT_FOUR) + "-" +
120             tmp.substr(CONSTANT_SIXTEEN, CONSTANT_FOUR) + "-" +
121             tmp.substr(CONSTANT_TWENTY);
122 
123     return ret;
124 }
125 
CompareTo(const UUID & val) const126 int UUID::CompareTo(const UUID &val) const
127 {
128     UUID tmp = val;
129     return this->ToString().compare(tmp.ToString());
130 }
131 
Equals(const UUID & val) const132 bool UUID::Equals(const UUID &val) const
133 {
134     for (int i = 0; i < UUID::UUID128_BYTES_LEN; i++) {
135         if (this->uuid_[i] != val.uuid_[i]) {
136             return false;
137         }
138     }
139     return true;
140 }
141 
GetLeastSignificantBits() const142 uint64_t UUID::GetLeastSignificantBits() const
143 {
144     uint64_t leastSigBits = 0;
145     for (int i = UUID::UUID128_BYTES_LEN / 2; i < UUID::UUID128_BYTES_LEN; i++) { // uuid长度/2作为i初始值
146         leastSigBits = (leastSigBits << 8) | (uuid_[i] & 0xFF); // 左移8位
147     }
148     return leastSigBits;
149 }
150 
GetMostSignificantBits() const151 uint64_t UUID::GetMostSignificantBits() const
152 {
153     uint64_t mostSigBits = 0;
154     for (int i = 0 / 2; i < UUID::UUID128_BYTES_LEN / 2; i++) { // uuid长度/2作为i最大值
155         mostSigBits = (mostSigBits << 8) | (uuid_[i] & 0xFF); // 左移8位
156     }
157     return mostSigBits;
158 }
159 
ConvertFrom128Bits(const std::array<uint8_t,UUID::UUID128_BYTES_LEN> & name)160 UUID UUID::ConvertFrom128Bits(const std::array<uint8_t, UUID::UUID128_BYTES_LEN> &name)
161 {
162     UUID tmp;
163     for (int i = 0; i < UUID::UUID128_BYTES_LEN; i++) {
164         tmp.uuid_[i] = name[i];
165     }
166     return tmp;
167 }
168 
ConvertTo128Bits() const169 std::array<uint8_t, UUID::UUID128_BYTES_LEN> UUID::ConvertTo128Bits() const
170 {
171     std::array<uint8_t, UUID::UUID128_BYTES_LEN> uuid;
172 
173     for (int i = 0; i < UUID::UUID128_BYTES_LEN; i++) {
174         uuid[i] = uuid_[i];
175     }
176 
177     return uuid;
178 }
179 
operator ==(const UUID & rhs) const180 bool UUID::operator==(const UUID &rhs) const
181 {
182     return uuid_ == rhs.uuid_;
183 }
184 
operator <(const UUID & uuid) const185 bool UUID::operator<(const UUID &uuid) const
186 {
187     return !Equals(uuid);
188 }
189 
IsValidUuid(std::string uuid)190 bool IsValidUuid(std::string uuid)
191 {
192     return regex_match(uuid, uuidRegex);
193 }
194 }
195 }