1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 00:31:58 +00:00

[core] Add integer overload for fnv1a_hash_extend (#13054)

This commit is contained in:
J. Nick Koston
2026-01-07 08:27:58 -10:00
committed by GitHub
parent 2830c7dab8
commit 0948e0359f
5 changed files with 18 additions and 4 deletions

View File

@@ -31,7 +31,11 @@ void BME68xBSEC2I2CComponent::dump_config() {
BME68xBSEC2Component::dump_config();
}
uint32_t BME68xBSEC2I2CComponent::get_hash() { return fnv1_hash("bme68x_bsec_state_" + to_string(this->address_)); }
uint32_t BME68xBSEC2I2CComponent::get_hash() {
char buf[22]; // "bme68x_bsec_state_" (18) + uint8_t max (3) + null
snprintf(buf, sizeof(buf), "bme68x_bsec_state_%u", this->address_);
return fnv1_hash(buf);
}
int8_t BME68xBSEC2I2CComponent::read_bytes_wrapper(uint8_t a_register, uint8_t *data, uint32_t len, void *intfPtr) {
ESP_LOGVV(TAG, "read_bytes_wrapper: reg = %u", a_register);

View File

@@ -158,7 +158,7 @@ void SEN5XComponent::setup() {
// Hash with config hash, version, and serial number
// This ensures the baseline storage is cleared after OTA
// Serial numbers are unique to each sensor, so multiple sensors can be used without conflict
uint32_t hash = fnv1a_hash_extend(App.get_config_version_hash(), std::to_string(combined_serial));
uint32_t hash = fnv1a_hash_extend(App.get_config_version_hash(), combined_serial);
this->pref_ = global_preferences->make_preference<Sen5xBaselines>(hash, true);
if (this->pref_.load(&this->voc_baselines_storage_)) {

View File

@@ -75,7 +75,7 @@ void SGP30Component::setup() {
// Hash with config hash, version, and serial number
// This ensures the baseline storage is cleared after OTA
// Serial numbers are unique to each sensor, so multiple sensors can be used without conflict
uint32_t hash = fnv1a_hash_extend(App.get_config_version_hash(), std::to_string(this->serial_number_));
uint32_t hash = fnv1a_hash_extend(App.get_config_version_hash(), this->serial_number_);
this->pref_ = global_preferences->make_preference<SGP30Baselines>(hash, true);
if (this->store_baseline_ && this->pref_.load(&this->baselines_storage_)) {

View File

@@ -60,7 +60,7 @@ void SGP4xComponent::setup() {
// Hash with config hash, version, and serial number
// This ensures the baseline storage is cleared after OTA
// Serial numbers are unique to each sensor, so multiple sensors can be used without conflict
uint32_t hash = fnv1a_hash_extend(App.get_config_version_hash(), std::to_string(this->serial_number_));
uint32_t hash = fnv1a_hash_extend(App.get_config_version_hash(), this->serial_number_);
this->pref_ = global_preferences->make_preference<SGP4xBaselines>(hash, true);
if (this->pref_.load(&this->voc_baselines_storage_)) {

View File

@@ -404,6 +404,16 @@ constexpr uint32_t fnv1a_hash_extend(uint32_t hash, const char *str) {
inline uint32_t fnv1a_hash_extend(uint32_t hash, const std::string &str) {
return fnv1a_hash_extend(hash, str.c_str());
}
/// Extend a FNV-1a hash with an integer (hashes each byte).
template<std::integral T> constexpr uint32_t fnv1a_hash_extend(uint32_t hash, T value) {
using UnsignedT = std::make_unsigned_t<T>;
UnsignedT uvalue = static_cast<UnsignedT>(value);
for (size_t i = 0; i < sizeof(T); i++) {
hash ^= (uvalue >> (i * 8)) & 0xFF;
hash *= FNV1_PRIME;
}
return hash;
}
/// Calculate a FNV-1a hash of \p str.
constexpr uint32_t fnv1a_hash(const char *str) { return fnv1a_hash_extend(FNV1_OFFSET_BASIS, str); }
inline uint32_t fnv1a_hash(const std::string &str) { return fnv1a_hash(str.c_str()); }