• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2025 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 <cstdint>
17 #include <cstdlib>
18 #include <array>
19 #include <sstream>
20 #include <securec.h>
21 #include <sys/types.h>
22 #include <random>
23 
24 #include "tools/format_logger.h"
25 #include "Util.h"
26 #include "stdlib/native/core/stdlib_ani_helpers.h"
27 
28 namespace ark::ets::sdk::util {
29 
30 constexpr int UUID_LEN = 37;
31 constexpr uint32_t NULL_FOUR_HIGH_BITS_IN_16 = 0x0FFF;
32 constexpr uint32_t RFC4122_UUID_VERSION_MARKER = 0x4000;
33 constexpr uint32_t NULL_TWO_HIGH_BITS_IN_16 = 0x3FFF;
34 constexpr uint32_t RFC4122_UUID_RESERVED_BITS = 0x8000;
35 
36 template <typename S>
GenRandUint()37 S GenRandUint()
38 {
39     static auto device = std::random_device();
40     static auto randomGenerator = std::mt19937(device());
41     static auto range = std::uniform_int_distribution<S>();
42 
43     return range(randomGenerator);
44 }
45 
GenUuid4(ani_env * env)46 std::string GenUuid4(ani_env *env)
47 {
48     std::array<char, UUID_LEN> uuidStr = {0};
49     // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
50     int n = snprintf_s(
51         uuidStr.begin(), UUID_LEN, UUID_LEN - 1, "%08x-%04x-%04x-%04x-%012x", GenRandUint<uint32_t>(),
52         GenRandUint<uint16_t>(), (GenRandUint<uint16_t>() & NULL_FOUR_HIGH_BITS_IN_16) | RFC4122_UUID_VERSION_MARKER,
53         (GenRandUint<uint16_t>() & NULL_TWO_HIGH_BITS_IN_16) | RFC4122_UUID_RESERVED_BITS, GenRandUint<uint64_t>());
54     if ((n < 0) || (n > static_cast<int>(UUID_LEN))) {
55         stdlib::ThrowNewError(env, "Lstd/core/RuntimeException;", "GenerateRandomUUID failed", "Lstd/core/String;:V");
56         return std::string();
57     }
58     std::stringstream res;
59     res << uuidStr.data();
60 
61     return res.str();
62 }
63 
64 extern "C" {
ETSApiUtilHelperGenerateRandomUUID(ani_env * env,ani_class klass,ani_boolean entropyCache)65 ANI_EXPORT ani_string ETSApiUtilHelperGenerateRandomUUID(ani_env *env, [[maybe_unused]] ani_class klass,
66                                                          ani_boolean entropyCache)
67 {
68     static std::string lastGeneratedUUID;
69     if (entropyCache != ANI_TRUE || lastGeneratedUUID.empty()) {
70         lastGeneratedUUID = GenUuid4(env);
71     }
72     return stdlib::CreateUtf8String(env, lastGeneratedUUID.data(), lastGeneratedUUID.size());
73 }
74 }  // extern "C"
75 
76 }  // namespace ark::ets::sdk::util
77