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()53Uuid::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)101char 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) const112void 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