diff --git a/core/ustring.cpp b/core/ustring.cpp
index 3df30e096d6d..6ed96a6803c3 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -38,6 +38,7 @@
#include "core/crypto/crypto_core.h"
#include "core/math/math_funcs.h"
#include "core/os/memory.h"
+#include "core/os/os.h"
#include "core/print_string.h"
#include "core/translation.h"
#include "core/ucaps.h"
@@ -1004,6 +1005,46 @@ const CharType *String::c_str() const {
return size() ? &operator[](0) : &zero;
}
+String String::uuidv4_text() {
+ uint32_t timestamp = OS::get_singleton()->get_unix_time();
+ uint32_t ticks = OS::get_singleton()->get_ticks_msec();
+ uint8_t bytes[16] = {
+ // time low
+ (uint8_t)((timestamp)&0xff),
+ (uint8_t)((timestamp << 1) & 0xff),
+ (uint8_t)((timestamp << 2) & 0xff),
+ (uint8_t)((timestamp << 3) & 0xff),
+
+ // time mid
+ (uint8_t)((timestamp << 4) & 0xff),
+ (uint8_t)((timestamp << 5) & 0xff),
+
+ // time high
+ (uint8_t)((timestamp << 6) & 0xff),
+ (uint8_t)((timestamp << 7) & 0xff),
+
+ // clock seq hi
+ (uint8_t)(((ticks << 1) & 0x0f) | 0x40),
+
+ // clock seq low
+ (uint8_t)((ticks)&0xff),
+
+ // node
+ (uint8_t)((Math::rand() & 0x3f) | 0x80),
+ (uint8_t)(Math::rand() & 0xff),
+ (uint8_t)(Math::rand() & 0xff),
+ (uint8_t)(Math::rand() & 0xff),
+ (uint8_t)(Math::rand() & 0xff),
+ (uint8_t)(Math::rand() & 0xff)
+ };
+
+ return String::hex_encode_buffer(bytes, 16)
+ .insert(8, "-")
+ .insert(13, "-")
+ .insert(18, "-")
+ .insert(23, "-");
+}
+
String String::md5(const uint8_t *p_md5) {
return String::hex_encode_buffer(p_md5, 16);
}
diff --git a/core/ustring.h b/core/ustring.h
index 5bf73001aa18..2080832b5228 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -240,6 +240,7 @@ class String {
static String num_int64(int64_t p_num, int base = 10, bool capitalize_hex = false);
static String num_uint64(uint64_t p_num, int base = 10, bool capitalize_hex = false);
static String chr(CharType p_char);
+ static String uuidv4_text();
static String md5(const uint8_t *p_md5);
static String hex_encode_buffer(const uint8_t *p_buffer, int p_len);
bool is_numeric() const;
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index 93ce9870c9f2..4ca48c9c7fa2 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -1256,6 +1256,13 @@
[/codeblock]
+
+
+
+
+ Returns a random 128-bit [url=https://en.wikipedia.org/wiki/Universally_unique_identifier]universally unique identifier[/url]. Example returned value: [code]dd10eb87-1596-426f-9e1d-496e8ceea6ed[/code].
+
+
diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp
index 2d3812fc8c14..9570b0c7596f 100644
--- a/modules/gdscript/gdscript_functions.cpp
+++ b/modules/gdscript/gdscript_functions.cpp
@@ -116,6 +116,7 @@ const char *GDScriptFunctions::get_func_name(Function p_func) {
"print_debug",
"push_error",
"push_warning",
+ "uuidv4_text",
"var2str",
"str2var",
"var2bytes",
@@ -817,6 +818,9 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_
WARN_PRINTS(message);
r_ret = Variant();
} break;
+ case TEXT_UUIDV4: {
+ r_ret = String::uuidv4_text();
+ } break;
case VAR_TO_STR: {
VALIDATE_ARG_COUNT(1);
String vars;
@@ -1941,6 +1945,12 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) {
mi.return_val.type = Variant::NIL;
return mi;
+ } break;
+ case TEXT_UUIDV4: {
+ MethodInfo mi("uuidv4_text");
+ mi.return_val.type = Variant::STRING;
+ return mi;
+
} break;
case VAR_TO_STR: {
diff --git a/modules/gdscript/gdscript_functions.h b/modules/gdscript/gdscript_functions.h
index 1812ddf12141..62be547c0b17 100644
--- a/modules/gdscript/gdscript_functions.h
+++ b/modules/gdscript/gdscript_functions.h
@@ -107,6 +107,7 @@ class GDScriptFunctions {
TEXT_PRINT_DEBUG,
PUSH_ERROR,
PUSH_WARNING,
+ TEXT_UUIDV4,
VAR_TO_STR,
STR_TO_VAR,
VAR_TO_BYTES,