Has anybody got script, that converts DEC numbers to HEX number? If yes, please post here.
Hi,
basic idea for one HEX number, byte and longer needs loop and MODULO 16:
:local nibble 13
:log info ("HEX 0x".[:pick "0123456789ABCDEF" $nibble ($nibble+1)])
Hi Petr, how can I use this for big numbers. 1500, 16000 etc… My script is calculates sum of two HEX numbers, but Router OS shows me sum by DEC numbers.
[otgonkhuu@MikroTik] > :put [(0x4B0+0x1)]
1201
Is there any way to put results by HEX numbers?
I have tried to write script that can convert only 12 digits DEC numbers to HEX. Please give me advice how to better this script. How can I use loops for this script?
{:global m3 <Value(Max 12 digits)>
:global b1 [($m3/16)]
:global u1 [($m3-($b1*16))]
:global b2 [($b1/16)]
:global u2 [($b1-($b2*16))]
:global b3 [($b2/16)]
:global u3 [($b2-($b3*16))]
:global b4 [($b3/16)]
:global u4 [($b3-($b4*16))]
:global b5 [($b4/16)]
:global u5 [($b4-($b5*16))]
:global b6 [($b5/16)]
:global u6 [($b5-($b6*16))]
:global b7 [($b6/16)]
:global u7 [($b6-($b7*16))]
:global b8 [($b7/16)]
:global u8 [($b7-($b8*16))]
:global b9 [($b8/16)]
:global u9 [($b8-($b9*16))]
:global b10 [($b9/16)]
:global u10 [($b9-($b10*16))]
:if ($u3=10) do={:global u3 A} else={:if ($u3=11) do={:global u3 B} else={
:if ($u3=12) do={:global u3 C} else={:if ($u3=13) do={:global u3 D} else={
:if ($u3=14) do={:global u3 E} else={:if ($u3=15) do={:global u3 F} else={:nothing}}}}}}
:if ($u4=10) do={:global u4 A} else={:if ($u4=11) do={:global u4 B} else={
:if ($u4=12) do={:global u4 C} else={:if ($u4=13) do={:global u4 D} else={
:if ($u4=14) do={:global u4 E} else={:if ($u4=15) do={:global u4 F} else={:nothing}}}}}}
:if ($u5=10) do={:global u5 A} else={:if ($u5=11) do={:global u5 B} else={
:if ($u5=12) do={:global u5 C} else={:if ($u5=13) do={:global u5 D} else={
:if ($u5=14) do={:global u5 E} else={:if ($u5=15) do={:global u5 F} else={:nothing}}}}}}
:if ($u6=10) do={:global u6 A} else={:if ($u6=11) do={:global u6 B} else={
:if ($u6=12) do={:global u6 C} else={:if ($u6=13) do={:global u6 D} else={
:if ($u6=14) do={:global u6 E} else={:if ($u6=15) do={:global u6 F} else={:nothing}}}}}}
:if ($u7=10) do={:global u7 A} else={:if ($u7=11) do={:global u7 B} else={
:if ($u7=12) do={:global u7 C} else={:if ($u7=13) do={:global u7 D} else={
:if ($u7=14) do={:global u7 E} else={:if ($u7=15) do={:global u7 F} else={:nothing}}}}}}
:if ($u8=10) do={:global u8 A} else={:if ($u8=11) do={:global u8 B} else={
:if ($u8=12) do={:global u8 C} else={:if ($u8=13) do={:global u8 D} else={
:if ($u8=14) do={:global u8 E} else={:if ($u8=15) do={:global u8 F} else={:nothing}}}}}}
:if ($u9=10) do={:global u9 A} else={:if ($u9=11) do={:global u9 B} else={
:if ($u9=12) do={:global u9 C} else={:if ($u9=13) do={:global u9 D} else={
:if ($u9=14) do={:global u9 E} else={:if ($u9=15) do={:global u9 F} else={:nothing}}}}}}
:if ($u10=10) do={:global u10 A} else={:if ($u10=11) do={:global u10 B} else={
:if ($u10=12) do={:global u10 C} else={:if ($u10=13) do={:global u10 D} else={
:if ($u10=14) do={:global u10 E} else={:if ($u10=15) do={:global u10 F} else={:nothing}}}}}}
:global Result value=("$u10"."$u9"."$u8"."$u7"."$u6"."$u5"."$u4"."$u3"."$u2"."$u1")
:put $Result}
Today I tried to use loops for to better my script. But there is very strange problem that every single $u is okay (As you see, EE3C1CDFD). When $result concatenates all $u, it shows me only DD. Why? Where I`m wrong?
{:global b 12345678910
:global u
:global t
:global result
:while ($b>16) do={:global t [($b/16)]; :global u [($b-($t*16))]; :global b [($b/16)];
:if ($u=10) do={:global u A} else={:if ($u=11) do={:global u B} else={
:if ($u=12) do={:global u C} else={:if ($u=13) do={:global u D} else={
:if ($u=14) do={:global u E} else={:if ($u=15) do={:global u F} else={:nothing}}}}}}
:global result value=($u.$result); :put $u}
:global result value=($b.$result); :put $result}
E
E
3
C
1
C
D
F
D
2DD
When I remove all if conditions, as you see, all $u is ok and $result successfully concatenates all $u.
{:global b 12345678910
:global u
:global t
:global result
:while ($b>16) do={:global t [($b/16)]; :global u [($b-($t*16))]; :global b [($b/16)];
:global result value=($u.$result); :put $u}
:global result value=($b.$result); :put $result}
14
14
3
12
1
12
13
15
13
21315131211231414
So I think problem is in the converter of number to alphabet and I tested only this for all conditions (10,11,12,13,14 and 15). It works great. Can convert all condition to alphabet:
{global u 15;
:if ($u=10) do={:global u A} else={:if ($u=11) do={:global u B} else={
:if ($u=12) do={:global u C} else={:if ($u=13) do={:global u D} else={
:if ($u=14) do={:global u E} else={:if ($u=15) do={:global u F} else={:nothing}}}}}};
:put $u}
F
Please help me to solve this issue.
Hi
why you messing with :if’s?:
:local dec 3735928559
# set this to number of hex digit you want
:local hexdigit 8
:local nibble
:local hex ""
:for i from=1 to=$hexdigit step=1 do={
:set nibble ($dec&0xf)
:set hex ([:pick "0123456789ABCDEF" $nibble ($nibble+1)].$hex)
:set dec ($dec>>4)
}
:log info ("0x".$hex)
Hi,
one more compact version without modifiyng $dec, bit less readable:
:local dec 3735928559
# set this to number of hex digit you want
:local hexdigit 8
: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)
note that do … while loop with ($dec>>$i)=0 end condition don’t works for negative numbers, so i am using for loop
Hi Petr, thanks for your great idea. Yes, you are right. No need to check too many dummy conditions . I finished my script. Tested many times using big DEC numbers, it works very good.
{:global dec <DEC number>
:global result
:while ($dec>9) do={:local temp [($dec/16)]; :global rem [($dec-($temp*16))]; :global dec [($dec/16)];
:global rem [:pick "0123456789ABCDEF" $rem ($rem+1)];
:global result value=($rem.$result)}
:global result value=($dec.$result);
:put [:pick "$result" 0 ([:len [$result]]-1)]}
This script is the one section of speed booster based log reader. Please see below topic, if you are interested in it and help me please.
http://forum.mikrotik.com/t/script-based-on-logs/48049/1
Hi Petr,
Your script is better. My script works fine, but when it runs more than two times, from second results not correct. I cant find where I
m wrong. So I`m using your script. Thanks.
otgooneo,
Replace ‘:global’ with ‘:local’
This will mean variables are only local to that instance of the running script, and will not conflict when running 2 or more of the same script simultaneously.
EDIT: Also, a good practice is to only define the variable once (ex. only 1 ‘:local’ per variable). Further in the script, use ‘:set’ to modify the variable.
Thanks dssmiktik. If possible, please give some advice on my topic http://forum.mikrotik.com/t/script-based-on-logs/48049/1
System_Convert-Decimal-BaseX
Randy Graham
Converts any decimal number to the desired base system
Pass values from another program using the following global variables
Decimal number to convert
:global decnum
The base number, default is 16
:global base
:if ($base>0) do={} else={:set base 16}
The base number after conversion
:global basenum “”
Used as lookup no matter what base converted to.
:local chrtable [:toarray “0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f”]
Add remaining alphabet for fun. For Base up to 36. Have fun.
:local chrtable ($chrtable + [:toarray “g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z”])
Find highest base position
:local basedigits 0
:local basearray
:local bw
:local c
:local loop 1
:while ($loop=1 ) do={
:set bw 0
Calculate weight for base position - bd is $base digit to the power of base
:for c from=0 to=$basedigits step=1 do={
:set bw ($bw*$base)
:if ($bw=0) do={:set bw 1}
}
#Create weight table as we go.
:set basearray ($basearray + [:toarray $bw])
Use same base weight variable to provide results of testing weight positon
:set bw ($decnum/$bw)
If divisible by base position number then increment base digit to indicate highest
:if ($bw > 0) do={
:set basedigits ($basedigits+1)
} else={
:set loop 0
:set basedigits ($basedigits-1)
}
}
End of for c
Now do actual decimal number to base number conversion
Another decimal number variable used during conversion leaving original unchanged
:local dn $decnum
Base position value
:local bpv
Go through each base postion staring from highest
:for c from=$basedigits to=0 do={
Store base number for weight position
:set bpv ($dn/[:pick $basearray $c])
Reduce decimal number by amount of base position
:set dn ($dn-([:pick $basearray $c]*$bpv))
Use base number to get character from hex table and concatenate to basenum
:set basenum “$basenum$[:pick $chrtable $bpv]”
}