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