Community discussions

MikroTik App
 
bobwalker
just joined
Topic Author
Posts: 23
Joined: Sun Apr 03, 2011 6:07 am

How to covert int to hex type value and save it in a string?

Fri Dec 16, 2011 5:23 pm

How to covert int to hex type value and save it in a string?
It is like that Routeros doest have the script function (but have toarray,tobool,totime etc.).
Doesnt truely RouterOS have the script function coverting int to hex ??
I need it in a layer7filter-script.
Thanks!
Last edited by bobwalker on Fri Dec 16, 2011 5:39 pm, edited 1 time in total.
 
User avatar
TealFrog
just joined
Posts: 23
Joined: Sun Oct 02, 2011 11:56 am

Re: How to covert int to hex type value and save it in a str

Sun Dec 18, 2011 11:09 am

I don't recall where I found this, but it should help...
# $dec has decimal value to convert
:local dec 3735928559
# $hexdigit set this to number of hex digits (max) you want
:local hexdigit 8
# $hex is string containing hex value
:local hex ""
:for i from=0 to=(4*($hexdigit-1)) step=4 do={
   :set hex ([:pick "0123456789ABCDEF" (($dec>>$i)&0xf) ((($dec>>$i)&0xf)+1)].$hex)
}
:log info ("0x".$hex)
 
rrwakc
just joined
Posts: 10
Joined: Mon Jan 04, 2016 4:54 pm

Re: How to covert int to hex type value and save it in a string?

Fri Jul 23, 2021 11:20 pm

Is there a convenient way to convert in the opposite direction. From ASCII 2byte number to signed integer?
for example 0xFF85 to -123
Or at least some documentation regarding num and tonum functions beyond their wiki

found it fem minutes after posting question here (HexToNum and many others)
https://github.com/eworm-de/routeros-sc ... -functions
 
User avatar
eworm
Forum Guru
Forum Guru
Posts: 1087
Joined: Wed Oct 22, 2014 9:23 am
Location: Oberhausen, Germany
Contact:

Re: How to covert int to hex type value and save it in a string?

Sat Jul 24, 2021 12:55 am

😁
Glad you like it. 😊
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12438
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: How to covert int to hex type value and save it in a string?

Sat Jul 24, 2021 1:19 am

Some reasoning on this...

this function already exist on RouterOS, but I don't want to belittle anyone's work, it was just to let find out.

using this example, the second line is for simulating one string readed from other variables.
:put 0xFF85
:put [:tonum "0xFF85"]

The eworm function works, obviously :))
and this is a very great idea for solve mixed, upper or lowercase:
: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"]

whe have the same results:
65413

But is not what is wanted:
-123


2 Byte signed go to
-32.768 to 0 to 32767 (65536 possible values)
written on hex
(0x8000 + 0x0 = 8000) to (0x8000 + 0x7FFF = 0xFFFF) to 0x0 to 0x7FFF, simply most significative bit set = negative value

for obtain rapidly the wanted value, if decimal value from hex is > 32767, subtract 65536 to it, instead use directly the results.

65413 > 32767 ? Yes then 65413 - 65536 = -123


Using directly RouterOS (without create a function or add some sanity ckeck from the provided value):
:global lazyvar "FF85"
:set lazyvar [:tonum ("0x".$lazyvar)]
:if ($lazyvar > 32767) do={:set lazyvar ($lazyvar - 65536)}
:put $lazyvar
:set lazyvar


Using Earthworm Jim*** function (without add some sanity ckeck from the provided value):
: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"]

***: do not offend, is one of my preferred game when I'm young, and is still on my heart
Last edited by rextended on Mon Nov 15, 2021 2:54 am, edited 1 time in total.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12438
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: How to covert int to hex type value and save it in a string?  [SOLVED]

Sat Jul 24, 2021 3:34 am

search tag # rextended int2hex num2hex integer number hexadecimal convert function

Function to convert integer to hex (only positive numbers)
: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]

For simple 0-255 to 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
}

the script here
viewtopic.php?f=2&t=57665&p=868898#p295501
must be simply updated and converted on a function and work better than mine to convert for example integer to signed Single Word Hexadecimal value,
with "right" byte shift and "and 0xf" can convert easily -123 on 2 signed byte to 0xFF85
Probably a reverse-function can be writed based on that method.
Last edited by rextended on Sun Feb 12, 2023 5:49 am, edited 4 times in total.
 
User avatar
eworm
Forum Guru
Forum Guru
Posts: 1087
Joined: Wed Oct 22, 2014 9:23 am
Location: Oberhausen, Germany
Contact:

Re: How to covert int to hex type value and save it in a string?

Sun Jul 25, 2021 12:29 am

I did not know that :tonum can handle hex input... That could simplify my function a lot.
Guess I will not drop it completely, currently it understands converting internal ids (like *d3f) directly.

BTW, RouterOS handles up to 60 bit unsigned values (0xfffffffffffffff), as does my function. No idea why you want to limit to 16 bit signed values?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12438
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: How to covert int to hex type value and save it in a string?

Sun Jul 25, 2021 12:39 am

You do not notice the request from @rrwakc on previous post? :))
viewtopic.php?f=2&t=57665&p=869033#p868885

I do not know why need that, but is for convert single word signed hex to integer

0xFF85 to -123
 
User avatar
eworm
Forum Guru
Forum Guru
Posts: 1087
Joined: Wed Oct 22, 2014 9:23 am
Location: Oberhausen, Germany
Contact:

Re: How to covert int to hex type value and save it in a string?

Sun Jul 25, 2021 12:44 am

Ah, indeed missed that detail... My fault.
Now your explanation makes perfectly sense. 😉
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12438
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: How to covert int to hex type value and save it in a string?

Sun Jul 25, 2021 12:45 am

Now the forum is more rich on functions ;))
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12438
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: How to covert int to hex type value and save it in a string?

Sun Jul 25, 2021 12:46 am

I really appreciate this:
:local Hex "0123456789abcdef_eworm.de_ABCDEF"
[:find $Hex ... ] % 16

I was very impressed with the simplicity of the solution ....
 
rrwakc
just joined
Posts: 10
Joined: Mon Jan 04, 2016 4:54 pm

Re: How to covert int to hex type value and save it in a string?

Wed Jul 28, 2021 11:20 pm

You do not notice the request from @rrwakc on previous post? :))
viewtopic.php?f=2&t=57665&p=869033#p868885

I do not know why need that, but is for convert single word signed hex to integer

0xFF85 to -123
TLDR: Temperature in °C also gets negative.

Mikrotik released KNOT, which also has GPIO ports, MQTT publisher and BLE(bluetooth low energy)
There is a firmware hack to make cheap BLE temperature humidity sensors behave like standard BLE 0x181A Environmental sensors (google: Custom Firmware On Xiaomi Thermometers)
Bluetooth GATT id of 0x0181A represent standard environmental sensors that provide temperature as 16bit signed in HEX.
Extract the 4 hex characters, convert to decimal and divide by 10 and you get -12.3°C to send over MQTT
At the end you get a nice modular smart-home setup managed as all other Mikrotik devices (+decoder as script)

With all the new IoT devices coming I would not be surprised to see dedicated chapter here for IoT, MQTT, NB-IoT, Scriping etc.
Now that the MQTT client module is available someone with good scripting skills might probably be able to send traffic and networks statistics from 100s of old mikrotik devices to mqtt broker and some database from there.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12438
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: How to covert int to hex type value and save it in a string?

Thu Jul 29, 2021 12:15 am

I hope you like those functions
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4093
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: How to covert int to hex type value and save it in a string?

Fri May 31, 2024 7:59 pm

I hope you like those functions
@rextended, FWIW your num2hex function still comes in handy... While num2hex is super helpful, half the code is doing that one conversion ;): viewtopic.php?t=204990#p1078202

Since despite the new built-in ":convert", still cannot do "num2hex" and it just assumes strings, so you get ASCII codes for "1", "6" as hex:
:put [:convert from=raw to=hex 16]
3136

While Mikrotik in 7.15 did add a "byte-array" that go to/from hex, so if the ints are in an array type, [:convert] can help some cases:
:put [:convert from=byte-array to=hex {255;255}] 
# ffff

And so the "numbyte2hex" for the "one hex char" case can be reduced, in 7.15, to:
:global "numbyte2hex-using-convert" do={
    :return [:convert from=byte-array to=hex {$1}]
}

:put [$"numbyte2hex-using-convert" 255]
# ff

Not saying to replace your code — since you need 7.15 for the "byte-array". More FYI on the current state of these type conversions ;)

Who is online

Users browsing this forum: anav, codered1983, seriquiti, silviub, triodetube and 46 guests