195489c19Sopenharmony_ci/*
295489c19Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
395489c19Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
495489c19Sopenharmony_ci * you may not use this file except in compliance with the License.
595489c19Sopenharmony_ci * You may obtain a copy of the License at
695489c19Sopenharmony_ci *
795489c19Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
895489c19Sopenharmony_ci *
995489c19Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1095489c19Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1195489c19Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1295489c19Sopenharmony_ci * See the License for the specific language governing permissions and
1395489c19Sopenharmony_ci * limitations under the License.
1495489c19Sopenharmony_ci */
1595489c19Sopenharmony_ci
1695489c19Sopenharmony_ci#include "uuid.h"
1795489c19Sopenharmony_ci
1895489c19Sopenharmony_ci#define CONSTANT_ZERO 0
1995489c19Sopenharmony_ci#define CONSTANT_FOUR 4
2095489c19Sopenharmony_ci#define CONSTANT_EIGHT 8
2195489c19Sopenharmony_ci#define CONSTANT_TWELVE 12
2295489c19Sopenharmony_ci#define CONSTANT_SIXTEEN 16
2395489c19Sopenharmony_ci#define CONSTANT_TWENTY 20
2495489c19Sopenharmony_ci
2595489c19Sopenharmony_cinamespace OHOS {
2695489c19Sopenharmony_cinamespace Bluetooth {
2795489c19Sopenharmony_ciconst std::regex uuidRegex("^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$");
2895489c19Sopenharmony_ci
2995489c19Sopenharmony_ciUUID::UUID(const long mostSigBits, const long leastSigBits)
3095489c19Sopenharmony_ci{
3195489c19Sopenharmony_ci    this->uuid_[15] = static_cast<uint8_t>(leastSigBits & 0x00000000000000FF); // 15是uuid的数组下标
3295489c19Sopenharmony_ci    this->uuid_[14] = static_cast<uint8_t>((leastSigBits & 0x000000000000FF00) >> 8); // 14是uuid的数组下标,右移8位
3395489c19Sopenharmony_ci    // 13是uuid的数组下标,右移16位
3495489c19Sopenharmony_ci    this->uuid_[13] = static_cast<uint8_t>((leastSigBits & 0x0000000000FF0000) >> 16);
3595489c19Sopenharmony_ci    // 12是uuid的数组下标,右移24位
3695489c19Sopenharmony_ci    this->uuid_[12] = static_cast<uint8_t>((leastSigBits & 0x00000000FF000000) >> 24);
3795489c19Sopenharmony_ci    // 11是uuid的数组下标,右移32位
3895489c19Sopenharmony_ci    this->uuid_[11] = static_cast<uint8_t>((leastSigBits & 0x000000FF00000000) >> 32);
3995489c19Sopenharmony_ci    // 10是uuid的数组下标,右移40位
4095489c19Sopenharmony_ci    this->uuid_[10] = static_cast<uint8_t>((leastSigBits & 0x0000FF0000000000) >> 40);
4195489c19Sopenharmony_ci    this->uuid_[9] = static_cast<uint8_t>((leastSigBits & 0x00FF000000000000) >> 48); // 9是uuid的数组下标,右移48位
4295489c19Sopenharmony_ci    this->uuid_[8] = static_cast<uint8_t>((leastSigBits & 0xFF00000000000000) >> 56); // 8是uuid的数组下标,右移56位
4395489c19Sopenharmony_ci    this->uuid_[7] = static_cast<uint8_t>(mostSigBits & 0x00000000000000FF); // 7是uuid的数组下标,右移8位
4495489c19Sopenharmony_ci    this->uuid_[6] = static_cast<uint8_t>((mostSigBits & 0x000000000000FF00) >> 8); // 6是uuid的数组下标,右移8位
4595489c19Sopenharmony_ci    this->uuid_[5] = static_cast<uint8_t>((mostSigBits & 0x0000000000FF0000) >> 16); // 5是uuid的数组下标,右移16位
4695489c19Sopenharmony_ci    this->uuid_[4] = static_cast<uint8_t>((mostSigBits & 0x00000000FF000000) >> 24); // 4是uuid的数组下标,右移24位
4795489c19Sopenharmony_ci    this->uuid_[3] = static_cast<uint8_t>((mostSigBits & 0x000000FF00000000) >> 32); // 3是uuid的数组下标,右移32位
4895489c19Sopenharmony_ci    this->uuid_[2] = static_cast<uint8_t>((mostSigBits & 0x0000FF0000000000) >> 40); // 2是uuid的数组下标,右移40位
4995489c19Sopenharmony_ci    this->uuid_[1] = static_cast<uint8_t>((mostSigBits & 0x00FF000000000000) >> 48); // 1是uuid的数组下标,右移48位
5095489c19Sopenharmony_ci    this->uuid_[0] = static_cast<uint8_t>((mostSigBits & 0xFF00000000000000) >> 56); // 0是uuid的数组下标,右移56位
5195489c19Sopenharmony_ci}
5295489c19Sopenharmony_ci
5395489c19Sopenharmony_ciUUID UUID::FromString(const std::string &name)
5495489c19Sopenharmony_ci{
5595489c19Sopenharmony_ci    UUID ret;
5695489c19Sopenharmony_ci    std::string tmp = name;
5795489c19Sopenharmony_ci    std::size_t pos = tmp.find("-");
5895489c19Sopenharmony_ci
5995489c19Sopenharmony_ci    while (pos != std::string::npos) {
6095489c19Sopenharmony_ci        tmp.replace(pos, 1, "");
6195489c19Sopenharmony_ci        pos = tmp.find("-");
6295489c19Sopenharmony_ci    }
6395489c19Sopenharmony_ci
6495489c19Sopenharmony_ci    for (std::size_t i = 0; (i + 1) < tmp.length();) {
6595489c19Sopenharmony_ci        ret.uuid_[i / 2] = std::stoi(tmp.substr(i, 2), nullptr, 16); // uuid的长度为16,i / 2作为uuid的数组下标
6695489c19Sopenharmony_ci        i += 2; // for 循环中,每轮增加2
6795489c19Sopenharmony_ci    }
6895489c19Sopenharmony_ci
6995489c19Sopenharmony_ci    return ret;
7095489c19Sopenharmony_ci}
7195489c19Sopenharmony_ci
7295489c19Sopenharmony_ciUUID UUID::RandomUUID()
7395489c19Sopenharmony_ci{
7495489c19Sopenharmony_ci    UUID random;
7595489c19Sopenharmony_ci
7695489c19Sopenharmony_ci    struct timeval tv;
7795489c19Sopenharmony_ci    struct timezone tz;
7895489c19Sopenharmony_ci    struct tm randomTime;
7995489c19Sopenharmony_ci    unsigned int randNum = 0;
8095489c19Sopenharmony_ci
8195489c19Sopenharmony_ci    rand_r(&randNum);
8295489c19Sopenharmony_ci    gettimeofday(&tv, &tz);
8395489c19Sopenharmony_ci    localtime_r(&tv.tv_sec, &randomTime);
8495489c19Sopenharmony_ci    random.uuid_[15] = static_cast<uint8_t>(tv.tv_usec & 0x00000000000000FF); // 15是uuid的数组下标
8595489c19Sopenharmony_ci    random.uuid_[14] = static_cast<uint8_t>((tv.tv_usec & 0x000000000000FF00) >> 8); // 14是uuid的数组下标,右移8位
8695489c19Sopenharmony_ci    random.uuid_[13] = static_cast<uint8_t>((tv.tv_usec & 0x0000000000FF0000) >> 16); // 13是uuid的数组下标,右移16位
8795489c19Sopenharmony_ci    random.uuid_[12] = static_cast<uint8_t>((tv.tv_usec & 0x00000000FF000000) >> 24); // 12是uuid的数组下标,右移24位
8895489c19Sopenharmony_ci    random.uuid_[10] = static_cast<uint8_t>((tv.tv_usec & 0x000000FF00000000) >> 32); // 10是uuid的数组下标,右移32位
8995489c19Sopenharmony_ci    random.uuid_[9] = static_cast<uint8_t>((tv.tv_usec & 0x0000FF0000000000) >> 40); // 9是uuid的数组下标,右移40位
9095489c19Sopenharmony_ci    random.uuid_[8] = static_cast<uint8_t>((tv.tv_usec & 0x00FF000000000000) >> 48); // 8是uuid的数组下标,右移48位
9195489c19Sopenharmony_ci    random.uuid_[7] = static_cast<uint8_t>((tv.tv_usec & 0xFF00000000000000) >> 56); // 7是uuid的数组下标,右移56位
9295489c19Sopenharmony_ci    // 6是uuid的数组下标
9395489c19Sopenharmony_ci    random.uuid_[6] = static_cast<uint8_t>((randomTime.tm_sec + static_cast<int>(randNum)) & 0xFF);
9495489c19Sopenharmony_ci    // 5是uuid的数组下标,右移8位
9595489c19Sopenharmony_ci    random.uuid_[5] = static_cast<uint8_t>((randomTime.tm_min + (randNum >> 8)) & 0xFF);
9695489c19Sopenharmony_ci    // 4是uuid的数组下标,右移16位
9795489c19Sopenharmony_ci    random.uuid_[4] = static_cast<uint8_t>((randomTime.tm_hour + (randNum >> 16)) & 0xFF);
9895489c19Sopenharmony_ci    // 3是uuid的数组下标,右移24位
9995489c19Sopenharmony_ci    random.uuid_[3] = static_cast<uint8_t>((randomTime.tm_mday + (randNum >> 24)) & 0xFF);
10095489c19Sopenharmony_ci    random.uuid_[2] = static_cast<uint8_t>(randomTime.tm_mon & 0xFF); // 2是uuid的数组下标
10195489c19Sopenharmony_ci    random.uuid_[1] = static_cast<uint8_t>(randomTime.tm_year & 0xFF); // 1是uuid的数组下标
10295489c19Sopenharmony_ci    random.uuid_[0] = static_cast<uint8_t>((randomTime.tm_year & 0xFF00) >> 8); // 0是uuid的数组下标,右移8位
10395489c19Sopenharmony_ci    return random;
10495489c19Sopenharmony_ci}
10595489c19Sopenharmony_ci
10695489c19Sopenharmony_cistd::string UUID::ToString() const
10795489c19Sopenharmony_ci{
10895489c19Sopenharmony_ci    std::string tmp = "";
10995489c19Sopenharmony_ci    std::string ret = "";
11095489c19Sopenharmony_ci    static const char *hex = "0123456789ABCDEF";
11195489c19Sopenharmony_ci
11295489c19Sopenharmony_ci    for (auto it = this->uuid_.begin(); it != this->uuid_.end(); it++) {
11395489c19Sopenharmony_ci        tmp.push_back(hex[(((*it) >> 4) & 0xF)]); // 右移4位
11495489c19Sopenharmony_ci        tmp.push_back(hex[(*it) & 0xF]);
11595489c19Sopenharmony_ci    }
11695489c19Sopenharmony_ci    // ToString操作,8, 4, 12, 16,20 作为截取字符的开始位置或截取长度
11795489c19Sopenharmony_ci    ret = tmp.substr(CONSTANT_ZERO, CONSTANT_EIGHT) + "-" +
11895489c19Sopenharmony_ci            tmp.substr(CONSTANT_EIGHT, CONSTANT_FOUR) + "-" +
11995489c19Sopenharmony_ci            tmp.substr(CONSTANT_TWELVE, CONSTANT_FOUR) + "-" +
12095489c19Sopenharmony_ci            tmp.substr(CONSTANT_SIXTEEN, CONSTANT_FOUR) + "-" +
12195489c19Sopenharmony_ci            tmp.substr(CONSTANT_TWENTY);
12295489c19Sopenharmony_ci
12395489c19Sopenharmony_ci    return ret;
12495489c19Sopenharmony_ci}
12595489c19Sopenharmony_ci
12695489c19Sopenharmony_ciint UUID::CompareTo(const UUID &val) const
12795489c19Sopenharmony_ci{
12895489c19Sopenharmony_ci    UUID tmp = val;
12995489c19Sopenharmony_ci    return this->ToString().compare(tmp.ToString());
13095489c19Sopenharmony_ci}
13195489c19Sopenharmony_ci
13295489c19Sopenharmony_cibool UUID::Equals(const UUID &val) const
13395489c19Sopenharmony_ci{
13495489c19Sopenharmony_ci    for (int i = 0; i < UUID::UUID128_BYTES_LEN; i++) {
13595489c19Sopenharmony_ci        if (this->uuid_[i] != val.uuid_[i]) {
13695489c19Sopenharmony_ci            return false;
13795489c19Sopenharmony_ci        }
13895489c19Sopenharmony_ci    }
13995489c19Sopenharmony_ci    return true;
14095489c19Sopenharmony_ci}
14195489c19Sopenharmony_ci
14295489c19Sopenharmony_ciuint64_t UUID::GetLeastSignificantBits() const
14395489c19Sopenharmony_ci{
14495489c19Sopenharmony_ci    uint64_t leastSigBits = 0;
14595489c19Sopenharmony_ci    for (int i = UUID::UUID128_BYTES_LEN / 2; i < UUID::UUID128_BYTES_LEN; i++) { // uuid长度/2作为i初始值
14695489c19Sopenharmony_ci        leastSigBits = (leastSigBits << 8) | (uuid_[i] & 0xFF); // 左移8位
14795489c19Sopenharmony_ci    }
14895489c19Sopenharmony_ci    return leastSigBits;
14995489c19Sopenharmony_ci}
15095489c19Sopenharmony_ci
15195489c19Sopenharmony_ciuint64_t UUID::GetMostSignificantBits() const
15295489c19Sopenharmony_ci{
15395489c19Sopenharmony_ci    uint64_t mostSigBits = 0;
15495489c19Sopenharmony_ci    for (int i = 0 / 2; i < UUID::UUID128_BYTES_LEN / 2; i++) { // uuid长度/2作为i最大值
15595489c19Sopenharmony_ci        mostSigBits = (mostSigBits << 8) | (uuid_[i] & 0xFF); // 左移8位
15695489c19Sopenharmony_ci    }
15795489c19Sopenharmony_ci    return mostSigBits;
15895489c19Sopenharmony_ci}
15995489c19Sopenharmony_ci
16095489c19Sopenharmony_ciUUID UUID::ConvertFrom128Bits(const std::array<uint8_t, UUID::UUID128_BYTES_LEN> &name)
16195489c19Sopenharmony_ci{
16295489c19Sopenharmony_ci    UUID tmp;
16395489c19Sopenharmony_ci    for (int i = 0; i < UUID::UUID128_BYTES_LEN; i++) {
16495489c19Sopenharmony_ci        tmp.uuid_[i] = name[i];
16595489c19Sopenharmony_ci    }
16695489c19Sopenharmony_ci    return tmp;
16795489c19Sopenharmony_ci}
16895489c19Sopenharmony_ci
16995489c19Sopenharmony_cistd::array<uint8_t, UUID::UUID128_BYTES_LEN> UUID::ConvertTo128Bits() const
17095489c19Sopenharmony_ci{
17195489c19Sopenharmony_ci    std::array<uint8_t, UUID::UUID128_BYTES_LEN> uuid;
17295489c19Sopenharmony_ci
17395489c19Sopenharmony_ci    for (int i = 0; i < UUID::UUID128_BYTES_LEN; i++) {
17495489c19Sopenharmony_ci        uuid[i] = uuid_[i];
17595489c19Sopenharmony_ci    }
17695489c19Sopenharmony_ci
17795489c19Sopenharmony_ci    return uuid;
17895489c19Sopenharmony_ci}
17995489c19Sopenharmony_ci
18095489c19Sopenharmony_cibool UUID::operator==(const UUID &rhs) const
18195489c19Sopenharmony_ci{
18295489c19Sopenharmony_ci    return uuid_ == rhs.uuid_;
18395489c19Sopenharmony_ci}
18495489c19Sopenharmony_ci
18595489c19Sopenharmony_cibool UUID::operator<(const UUID &uuid) const
18695489c19Sopenharmony_ci{
18795489c19Sopenharmony_ci    return !Equals(uuid);
18895489c19Sopenharmony_ci}
18995489c19Sopenharmony_ci
19095489c19Sopenharmony_cibool IsValidUuid(std::string uuid)
19195489c19Sopenharmony_ci{
19295489c19Sopenharmony_ci    return regex_match(uuid, uuidRegex);
19395489c19Sopenharmony_ci}
19495489c19Sopenharmony_ci}
19595489c19Sopenharmony_ci}