Страница 1 из 1

Функция хэширования строк для ROS7

Добавлено: 15 июн 2025, 14:27
Brook
Друзья всем привет.

Недавно возникла задача проверять наличие изменений в скриптах на устройствах сети. Самое простое решение - это хранить хэш скрипта и проверять его значение периодически. Если значения не совпадают - значит скрипт был изменен.

К сожалению в ROS нет отдельной функции хэширования. Решил написать свою.

Условия - хэш должен быть необратимым, уникальным и иметь фиксированную длину.

Данная функция это упрощённая версия известного алгоритма DJB2, который даёт хорошие распределение хешей. Выкладываю код для сообщества. Возможно кому-то пригодится.

Итак:
 strHash

Код: Выделить всё

:global strHash do={
#   input -  входная строка

# Преобразуем входную строку в массив байт
    :local bytes [:convert from=raw to=byte-array $input]

# Инициализируем хеш и маску (2^47-1) для ограничения размера
    :local hash 0
    :local mask 0x7FFFFFFFFFFF

# Проходим по каждому байту и перемешиваем биты
    :foreach b in=$bytes do={

# умножение на 33 (сдвиг влево на 5 и + hash)
        :set hash (($hash << 5) + $hash)

# побитовое XOR с кодом символа
        :set hash ($hash ^ $b)

# обрезаем число до 47 бит (маска 2^47-1)
        :set hash ($hash & $mask)
    }

# Превращаем число в строку и дополняем нулями до длины 15
    :local res [:tostr $hash]
    :while ([:len $res] < 15) do={:set res ("0".$res)}

    :return $res
}

- В этой функции сначала строка 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 символов во всех случаях.

Re: Функция хэширования строк для ROS7

Добавлено: 15 июн 2025, 15:49
Brook
Использование функции.

Код: Выделить всё

:put [$strHash input=[system/script/get scriptName source]]