From 6383eca54a043bfb736ee012178c9244f85c6081 Mon Sep 17 00:00:00 2001 From: Oxan van Leeuwen Date: Mon, 10 Jan 2022 01:50:26 +0100 Subject: [PATCH] Clean-up random helper functions (#3022) --- esphome/components/api/api_frame_helper.cpp | 2 +- .../light/addressable_light_effect.h | 5 +- esphome/core/helpers.cpp | 63 +++++++------------ esphome/core/helpers.h | 31 ++++----- 4 files changed, 40 insertions(+), 61 deletions(-) diff --git a/esphome/components/api/api_frame_helper.cpp b/esphome/components/api/api_frame_helper.cpp index 151c2512de..094dd67e33 100644 --- a/esphome/components/api/api_frame_helper.cpp +++ b/esphome/components/api/api_frame_helper.cpp @@ -721,7 +721,7 @@ APIError APINoiseFrameHelper::shutdown(int how) { } extern "C" { // declare how noise generates random bytes (here with a good HWRNG based on the RF system) -void noise_rand_bytes(void *output, size_t len) { esphome::fill_random(reinterpret_cast(output), len); } +void noise_rand_bytes(void *output, size_t len) { esphome::random_bytes(reinterpret_cast(output), len); } } #endif // USE_API_NOISE diff --git a/esphome/components/light/addressable_light_effect.h b/esphome/components/light/addressable_light_effect.h index 5091bae2d5..d404898edf 100644 --- a/esphome/components/light/addressable_light_effect.h +++ b/esphome/components/light/addressable_light_effect.h @@ -331,9 +331,10 @@ class AddressableFlickerEffect : public AddressableLightEffect { return; this->last_update_ = now; - fast_random_set_seed(random_uint32()); + uint32_t rng_state = random_uint32(); for (auto var : it) { - const uint8_t flicker = fast_random_8() % intensity; + rng_state = (rng_state * 0x9E3779B9) + 0x9E37; + const uint8_t flicker = (rng_state & 0xFF) % intensity; // scale down by random factor var = var.get() * (255 - flicker); diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index c039447fef..e15e3a8ea3 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -64,45 +64,6 @@ void set_mac_address(uint8_t *mac) { esp_base_mac_addr_set(mac); } std::string generate_hostname(const std::string &base) { return base + std::string("-") + get_mac_address(); } -uint32_t random_uint32() { -#ifdef USE_ESP32 - return esp_random(); -#elif defined(USE_ESP8266) - return os_random(); -#endif -} - -double random_double() { return random_uint32() / double(UINT32_MAX); } - -float random_float() { return float(random_double()); } - -void fill_random(uint8_t *data, size_t len) { -#if defined(USE_ESP_IDF) || defined(USE_ESP32_FRAMEWORK_ARDUINO) - esp_fill_random(data, len); -#elif defined(USE_ESP8266) - int err = os_get_random(data, len); - assert(err == 0); -#else -#error "No random source for this system config" -#endif -} - -static uint32_t fast_random_seed = 0; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) - -void fast_random_set_seed(uint32_t seed) { fast_random_seed = seed; } -uint32_t fast_random_32() { - fast_random_seed = (fast_random_seed * 2654435769ULL) + 40503ULL; - return fast_random_seed; -} -uint16_t fast_random_16() { - uint32_t rand32 = fast_random_32(); - return (rand32 & 0xFFFF) + (rand32 >> 16); -} -uint8_t fast_random_8() { - uint32_t rand32 = fast_random_32(); - return (rand32 & 0xFF) + ((rand32 >> 8) & 0xFF); -} - float gamma_correct(float value, float gamma) { if (value <= 0.0f) return 0.0f; @@ -314,6 +275,30 @@ IRAM_ATTR InterruptLock::~InterruptLock() { portENABLE_INTERRUPTS(); } // --------------------------------------------------------------------------------------------------------------------- +// Mathematics + +uint32_t random_uint32() { +#ifdef USE_ESP32 + return esp_random(); +#elif defined(USE_ESP8266) + return os_random(); +#else +#error "No random source available for this configuration." +#endif +} +float random_float() { return static_cast(random_uint32()) / static_cast(UINT32_MAX); } +void random_bytes(uint8_t *data, size_t len) { +#ifdef USE_ESP32 + esp_fill_random(data, len); +#elif defined(USE_ESP8266) + if (os_get_random(data, len) != 0) { + ESP_LOGE(TAG, "Failed to generate random bytes!"); + } +#else +#error "No random source available for this configuration." +#endif +} + // Strings std::string str_truncate(const std::string &str, size_t length) { diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 5f793df1ea..f4e814203f 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -78,25 +78,6 @@ template std::unique_ptr make_unique(Args &&... } #endif -/// Return a random 32 bit unsigned integer. -uint32_t random_uint32(); - -/** Returns a random double between 0 and 1. - * - * Note: This function probably doesn't provide a truly uniform distribution. - */ -double random_double(); - -/// Returns a random float between 0 and 1. Essentially just casts random_double() to a float. -float random_float(); - -void fill_random(uint8_t *data, size_t len); - -void fast_random_set_seed(uint32_t seed); -uint32_t fast_random_32(); -uint16_t fast_random_16(); -uint8_t fast_random_8(); - /// Applies gamma correction with the provided gamma to value. float gamma_correct(float value, float gamma); /// Reverts gamma correction with the provided gamma to value. @@ -304,6 +285,18 @@ constexpr uint64_t byteswap(uint64_t n) { return __builtin_bswap64(n); } ///@} +/// @name Mathematics +///@{ + +/// Return a random 32-bit unsigned integer. +uint32_t random_uint32(); +/// Return a random float between 0 and 1. +float random_float(); +/// Generate \p len number of random bytes. +void random_bytes(uint8_t *data, size_t len); + +///@} + /// @name Bit manipulation ///@{