Информация
Услуги
  • Внедрение
  • Настройка
  • Поддержка
  • Ремонт
Контакты
Новинка
Распродажа
Новости
Доставка
Оплата
Загрузки
  • Прошивки
    • WinBox
    • RouterOS
    • Мобильные приложения MikroTik
    • Архив
  • RouterOS
  • Мобильные приложения MikroTik
  • Архив
Форум
Настройка
    info@mikrotik.moscow
    +7 495 320-55-52
    Заказать звонок
    Mikrotik.moscow
    Каталог
    • Акции
      Акции
    • Маршрутизаторы
      Маршрутизаторы
    • Коммутаторы
      Коммутаторы
    • Радиомосты и уличные точки доступа
      Радиомосты и уличные точки доступа
    • Wi-Fi для дома и офиса
      Wi-Fi для дома и офиса
    • LTE/5G
      LTE/5G
    • Powerline адаптеры
      Powerline адаптеры
    • IoT устройства
      IoT устройства
    • Оборудование 60 ГГц
      Оборудование 60 ГГц
    • Материнские платы RouterBOARD
      Материнские платы RouterBOARD
    • Корпуса
      Корпуса
    • Интерфейсы
      Интерфейсы
    • SFP/QSFP трансиверы
      SFP/QSFP трансиверы
    • Аксессуары
      Аксессуары
    • Антенны
      Антенны
    • Архив
      Архив
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Скачать WinBox Скачать Прошивки Форум > RouterOS Форум > SwOS Форум > Железо
    Mikrotik.moscow
    Каталог
    Войти
    0 Сравнение
    0 Избранное
    0 Корзина
    Mikrotik.moscow
    Телефоны
    +7 495 320-55-52
    Заказать звонок
    0
    0
    0
    Mikrotik.moscow
    • +7 495 320-55-52
      • Назад
      • Телефоны
      • +7 495 320-55-52
      • Заказать звонок
    • info@mikrotik.moscow
    • г. Москва, ул. Бакунинская, 84
    • Пн-Пт: 09-00 до 18-00
      Сб-Вс: выходной


    • Кабинет
    • 0 Сравнение
    • 0 Избранное
    • 0 Корзина
    Главная
    Форум
    Форум
    RouterOS
    Как преобразовать int в значение типа hex и сохранить его в строке?

    Как преобразовать int в значение типа hex и сохранить его в строке?

    Форумы: RouterOS, Аппаратное обеспечение, SwOS, Обратная связь, Объявления, Сторонние инструменты
    Поиск  Пользователи  Правила  Войти
    Страницы: 1
    RSS
    Как преобразовать int в значение типа hex и сохранить его в строке?, RouterOS
     
    bobwalker
    Guest
    #1
    0
    16.12.2011 15:23:00
    Как преобразовать int в значение типа hex и сохранить его в строке? Вроде бы в RouterOS нет такой скриптовой функции (есть toarray, tobool, totime и т.д.). Неужели в RouterOS действительно нет функции в скриптах для конвертации int в hex? Мне это нужно для скрипта layer7filter. Спасибо!
     
     
     
    rrwakc
    Guest
    #2
    0
    23.07.2021 20:20:00
    Есть ли удобный способ сделать преобразование в обратную сторону? Из ASCII 2-байтового числа в знаковое целое? Например, 0xFF85 в -123. Или хотя бы какая-нибудь документация по функциям num и tonum, кроме той, что на вики. Я нашёл её спустя несколько минут после того, как задал вопрос здесь (HexToNum и много других) https://github.com/eworm-de/routeros-scripts/blob/main/global-functions
     
     
     
    eworm
    Guest
    #3
    0
    23.07.2021 21:55:00
    Рад, что тебе понравилось.
     
     
     
    rextended
    Guest
    #4
    0
    23.07.2021 22:19:00
    Немного рассуждений на эту тему… Такая функция уже есть в RouterOS, но я не хочу умалять чью-то работу, просто хотел поделиться находкой. В этом примере вторая строка симулирует чтение строки из других переменных:  
    :put 0xFF85  
    :put [:tonum "0xFF85"]

    Функция eworm работает, понятно же :)) И это классная идея для решения проблемы смешанных регистра букв (верхний или нижний):  

    :local Hex "0123456789abcdef_eworm.de_ABCDEF"  
    [:find $Hex … ] % 16

    :global HexToNum do={  
     :local Input [:tostr $1]
     :local Hex "0123456789abcdef_eworm.de_ABCDEF"  
     :local Multi 1; :local Return 0  
     :for I from=([:len $Input] - 1) to=0 do={
       :set Return ($Return + (([:find $Hex [:pick $Input $I]] % 16) * $Multi))
       :set Multi ($Multi * 16)  
     }  
     :return $Return  
    }  

    :put [$HexToNum "0xFF85"]

    У нас получается тот же результат: 65413. Но это не то, что нужно: -123. Двухбайтовое signed число может быть от -32 768 до 0 и до 32 767 (всего 65536 значений), записанных в hex: от (0x8000 + 0x0 = 8000) до (0x8000 + 0x7FFF = 0xFFFF), потом от 0x0 до 0x7FFF. По сути, если самый старший бит установлен — число считается отрицательным. Чтобы быстро получить нужное значение, если десятичное значение из hex больше 32767, надо отнять 65536 вместо того, чтобы просто использовать результат напрямую.  

    65413 > 32767? Да, значит 65413 - 65536 = -123.  

    Используя напрямую RouterOS (без создания функции и дополнительной проверки корректности входных данных):  

    :global lazyvar "FF85"  
    :set lazyvar [:tonum ("0x".$lazyvar)]
    :if ($lazyvar > 32767) do={:set lazyvar ($lazyvar - 65536)}  
    :put $lazyvar  

    Используя функцию из Earthworm Jim *** (тоже без доппроверки входных данных):  

    :global SingleWordHexToNum do={  
     :local Input [:tostr $1]
     :local Hex "0123456789abcdef_eworm.de_ABCDEF"  
     :local Multi 1; :local Return 0  
     :for I from=([:len $Input] - 1) to=0 do={
       :set Return ($Return + (([:find $Hex [:pick $Input $I]] % 16) * $Multi))
       :set Multi ($Multi * 16)  
     }  
     :if ($Return > 32767) do={ :return ($Return - 65536) } else={ :return $Return }  
    }  

    :put [$SingleWordHexToNum "0xFF85"]

    *** Не обижайтесь, это одна из моих любимых игр, когда я был молод, и она до сих пор занимает особое место в моём сердце.
     
     
     
    rextended
    Guest
    #5
    0
    24.07.2021 00:34:00
    search tag # rextended int2hex num2hex integer number hexadecimal convert function

    Функция для преобразования целого числа в шестнадцатеричное (только положительные числа):

    global num2hex do={
     local number [:tonum $1]
     local hexadec "0"
     local remainder 0
     local hexChars "0123456789ABCDEF"
     if ($number > 0) do={set hexadec ""}
     while ($number > 0) do={
           set remainder ($number % 16)
           set number (($number - $remainder) / 16)
           set hexadec ([:pick $hexChars $remainder].$hexadec)
     }
     if ([:len $hexadec] = 1) do={set hexadec "0$hexadec"}
     return "0x$hexadec"
    }

    put [$num2hex 7366]

    Для простого конверта от 0 до 255 в hex:

    global numbyte2hex do={
       local input [:tonum $1]
       local hexchars "0123456789ABCDEF"
       local convert [:pick $hexchars (($input >> 4) & 0xF)]
       set convert ($convert.[:pick $hexchars ($input & 0xF)])
       return $convert
    }

    Скрипт здесь https://forum.mikrotik.com/viewtopic.php?f=2&t=57665&p=868898#p295501 просто нужно обновить и переделать в функцию, которая будет работать лучше моей, чтобы, например, конвертировать целое число в signed Single Word Hexadecimal значение с «правильным» сдвигом байта и «and 0xf». Это легко конвертирует -123 в 2-байтовое signed значение 0xFF85.

    Наверное, можно написать и обратную функцию, основанную на этом методе.
     
     
     
    eworm
    Guest
    #6
    0
    24.07.2021 21:29:00
    Я не знал, что :tonum может работать с шестнадцатеричным вводом… Это могло бы значительно упростить мою функцию. Похоже, я не брошу её совсем, сейчас она напрямую понимает преобразование внутренних ID (типа * d3f). Кстати, RouterOS поддерживает значения до 60 бит без знака (0xfffffffffffffff), как и моя функция. Не понимаю, зачем тебе ограничиваться знаковыми 16-битными значениями?
     
     
     
    rextended
    Guest
    #7
    0
    24.07.2021 21:39:00
    Ты не заметил запрос от @rrwakc в предыдущем посте? :)) https://forum.mikrotik.com/viewtopic.php?f=2&t=57665&p=869033#p868885 Я не знаю, зачем это нужно, но речь о том, чтобы преобразовать одно слово с заданным знаком в число – например, 0xFF85 в -123.
     
     
     
    eworm
    Guest
    #8
    0
    24.07.2021 21:44:00
    Ах да, действительно пропустил эту деталь... Моя ошибка. Теперь твое объяснение стало абсолютно понятным.
     
     
     
    rextended
    Guest
    #9
    0
    24.07.2021 21:45:00
    Теперь форум стал гораздо богаче по функционалу ;))
     
     
     
    rextended
    Guest
    #10
    0
    24.07.2021 21:46:00
    Я очень ценю это: :local Hex “0123456789abcdef_eworm.de_ABCDEF” [:find $Hex … ] % 16. Меня действительно впечатлила простота решения…
     
     
     
    rrwakc
    Guest
    #11
    0
    28.07.2021 20:20:00
    Кратко: температура в градусах Цельсия может быть отрицательной. Mikrotik выпустил KNOT, который тоже имеет порты GPIO, MQTT-публикатор и BLE (bluetooth low energy). Есть прошивка, которая позволяет недорогим BLE датчикам температуры и влажности работать как стандартные BLE 0x181A Environmental sensors (ищите в гугле: Custom Firmware On Xiaomi Thermometers). Bluetooth GATT id 0x0181A — это стандартные датчики окружающей среды, которые выдают температуру в 16-битном знаковом HEX-формате. Берёшь 4 шестнадцатеричных символа, переводишь в десятичное число и делишь на 10 — получаешь, например, -12.3°C, чтобы отправить через MQTT. В итоге получается классная модульная умная система дома, которой можно управлять, как и всеми другими устройствами Mikrotik (+декодер в виде скрипта). С появлением новых IoT-устройств меня бы не удивило, если бы здесь появилась отдельная глава про IoT, MQTT, NB-IoT, скрипты и так далее. Теперь, когда доступен MQTT клиент, кто-то с хорошими навыками программирования, вероятно, сможет отправлять трафик и статистику по сети со сотен старых устройств Mikrotik на MQTT брокер и далее в базу данных.
     
     
     
    rextended
    Guest
    #12
    0
    28.07.2021 21:15:00
    Надеюсь, тебе понравятся эти функции.
     
     
     
    Amm0
    Guest
    #13
    0
    31.05.2024 16:59:00
    @rextended, кстати, твоя функция num2hex всё ещё очень полезна… Хотя num2hex реально выручает, половина кода уходит на одну и ту же конверсию: HOWTO: Импортировать участников ZeroTier в Mikrotik DNS с помощью $ZT2DNS. Несмотря на новый встроенный “:convert”, всё равно нельзя сделать “num2hex” — он просто воспринимает строки, поэтому для “1”, “6” выдаёт ASCII-коды в виде hex: :put [:convert from=raw to=hex 16]
    3136. В Mikrotik 7.15 добавили “byte-array” для конвертации в hex и обратно, так что если числа хранятся в массиве, [:convert] помогает в некоторых случаях: :put [:convert from=byte-array to=hex {255;255}]
    # ffff. Так что функцию “numbyte2hex” для одного hex-символа в 7.15 можно упростить до:  
    :global "numbyte2hex-using-convert" do={  
       :return [:convert from=byte-array to=hex {$1}]
    }  

    :put [$"numbyte2hex-using-convert" 255]
    # ff  
    Не говорю, что надо менять твой код — для “byte-array” нужна именно 7.15. Просто для информации о текущем состоянии этих типов конвертации.
     
     
     
    Страницы: 1
    Читают тему
    +7 495 320-55-52
    info@mikrotik.moscow
    Электрозаводская, Бауманская
    Москва, ул. Бакунинская, 84с21
    Конфиденциальность Оферта
    © 2026 «Mikrotik.Moscow»
    Главная Каталог 0 Корзина 0 Избранные Кабинет 0 Сравнение Акции Контакты Услуги Бренды Отзывы Компания Лицензии Документы Реквизиты Поиск Блог Обзоры