Функция хэширования строк для ROS7
Добавлено: 15 июн 2025, 14:27
Друзья всем привет.
Недавно возникла задача проверять наличие изменений в скриптах на устройствах сети. Самое простое решение - это хранить хэш скрипта и проверять его значение периодически. Если значения не совпадают - значит скрипт был изменен.
К сожалению в ROS нет отдельной функции хэширования. Решил написать свою.
Условия - хэш должен быть необратимым, уникальным и иметь фиксированную длину.
Данная функция это упрощённая версия известного алгоритма DJB2, который даёт хорошие распределение хешей. Выкладываю код для сообщества. Возможно кому-то пригодится.
Итак:
- В этой функции сначала строка input переводится в массив байт с помощью команды :convert from=raw to=byte-array, что позволяет обрабатывать каждый символ по его ASCII-коду.
- Дальше по каждому байту циклом переменная hash обновляется по формуле hash = hash * 33 XOR byte. Здесь используется сдвиг влево << 5 для умножения на 32 и добавление самого hash (в сумме получается умножение на 33), затем XOR (^) с кодом текущего байта. Такие операции (сдвиг и XOR) приводят к хорошему перемешиванию битов и затрудняют обратный анализ исходной строки.
- После каждой итерации результат маскируется битовой операцией & 0x7FFFFFFFFFFF, чтобы ограничить размер числа и не выйти за пределы точного представления (это эквивалентно взятию по модулю 2^47). Маска в коде задана как 0x7FFFFFFFFFFF (в шеснадцатеричной), что соответствует двоичному 47-битовому числу из единиц. Операция & гарантирует, что число hash всегда остается в диапазоне до 2^47–1.
- В конце полученное число конвертируется в десятичную строку через :tostr. Если строка короче 15 символов, слева добавляются нули (while (len<15) do={"0"+string}), чтобы итоговая длина хэша была ровно 15 символов во всех случаях.
Недавно возникла задача проверять наличие изменений в скриптах на устройствах сети. Самое простое решение - это хранить хэш скрипта и проверять его значение периодически. Если значения не совпадают - значит скрипт был изменен.
К сожалению в ROS нет отдельной функции хэширования. Решил написать свою.
Условия - хэш должен быть необратимым, уникальным и иметь фиксированную длину.
Данная функция это упрощённая версия известного алгоритма DJB2, который даёт хорошие распределение хешей. Выкладываю код для сообщества. Возможно кому-то пригодится.
Итак:
- В этой функции сначала строка input переводится в массив байт с помощью команды :convert from=raw to=byte-array, что позволяет обрабатывать каждый символ по его ASCII-коду.
- Дальше по каждому байту циклом переменная hash обновляется по формуле hash = hash * 33 XOR byte. Здесь используется сдвиг влево << 5 для умножения на 32 и добавление самого hash (в сумме получается умножение на 33), затем XOR (^) с кодом текущего байта. Такие операции (сдвиг и XOR) приводят к хорошему перемешиванию битов и затрудняют обратный анализ исходной строки.
- После каждой итерации результат маскируется битовой операцией & 0x7FFFFFFFFFFF, чтобы ограничить размер числа и не выйти за пределы точного представления (это эквивалентно взятию по модулю 2^47). Маска в коде задана как 0x7FFFFFFFFFFF (в шеснадцатеричной), что соответствует двоичному 47-битовому числу из единиц. Операция & гарантирует, что число hash всегда остается в диапазоне до 2^47–1.
- В конце полученное число конвертируется в десятичную строку через :tostr. Если строка короче 15 символов, слева добавляются нули (while (len<15) do={"0"+string}), чтобы итоговая длина хэша была ровно 15 символов во всех случаях.