Community discussions

MikroTik App
 
DyadyaGenya
Member Candidate
Member Candidate
Topic Author
Posts: 220
Joined: Mon May 08, 2023 10:34 pm

To determine the value of each bit in a byte.

Thu Jun 08, 2023 8:27 pm

How to check the value of a specific bit in a number expressed in hexadecimal format?
For example, if the number is represented in hexadecimal as "0x60", in binary it would be "01100000". How can we determine the value of, let's say, the 2nd or 7th bit? Are there any built-in functions for this in MikroTik?
I tried to do the following:
:local value 0x60;

:local bit0Value ( $value & 0x1 > 0 );
:put "The value of the 0 bit.: $bit0Value";

:local bit1Value ( $value & 0x2 > 0 );
:put "The value of the 1 bit.: $bit1Value";

:local bit2Value ( $value & 0x3 > 0 );
:put "The value of the 2 bit.: $bit2Value";

:local bit3Value ( $value & 0x4 > 0 );
:put "The value of the 3 bit.: $bit3Value";

:local bit4Value ( $value & 0x5 > 0 );
:put "The value of the 4 bit.: $bit4Value";

:local bit5Value ( $value & 0x6 > 0 );
:put "The value of the 5 bit.: $bit5Value";

:local bit6Value ( $value & 0x7 > 0 );
:put "The value of the 6 bit.: $bit6Value";

:local bit7Value ( $value & 0x8 > 0 );
:put "The value of the 7 bit.: $bit7Value";
The results do not match.
 
holvoetn
Forum Guru
Forum Guru
Posts: 5472
Joined: Tue Apr 13, 2021 2:14 am
Location: Belgium

Re: To determine the value of each bit in a byte.

Thu Jun 08, 2023 9:41 pm

Your hex values used for testing are wrong.

/system/script> run test
The value of the 0 bit.: false
The value of the 1 bit.: false
The value of the 2 bit.: false
The value of the 3 bit.: false
The value of the 4 bit.: false
The value of the 5 bit.: true
The value of the 6 bit.: true
The value of the 7 bit.: false

0x60 = 0110 0000, so 2 bits will return true.

And you need to test with moving bit, so
0x1, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
:local value 0x60;
:local bit0Value ( $value & 0x1 > 0 );
:put "The value of the 0 bit.: $bit0Value";

:local bit1Value ( $value & 0x2 > 0 );
:put "The value of the 1 bit.: $bit1Value";

:local bit2Value ( $value & 0x4 > 0 );
:put "The value of the 2 bit.: $bit2Value";

:local bit3Value ( $value & 0x8 > 0 );
:put "The value of the 3 bit.: $bit3Value";

:local bit4Value ( $value & 0x10 > 0 );
:put "The value of the 4 bit.: $bit4Value";

:local bit5Value ( $value & 0x20 > 0 );
:put "The value of the 5 bit.: $bit5Value";

:local bit6Value ( $value & 0x40> 0 );
:put "The value of the 6 bit.: $bit6Value";

:local bit7Value ( $value & 0x80 > 0 );
:put "The value of the 7 bit.: $bit7Value";
 
DyadyaGenya
Member Candidate
Member Candidate
Topic Author
Posts: 220
Joined: Mon May 08, 2023 10:34 pm

Re: To determine the value of each bit in a byte.

Thu Jun 08, 2023 10:08 pm

Your hex values used for testing are wrong.

/system/script> run test
The value of the 0 bit.: false
The value of the 1 bit.: false
The value of the 2 bit.: false
The value of the 3 bit.: false
The value of the 4 bit.: false
The value of the 5 bit.: true
The value of the 6 bit.: true
The value of the 7 bit.: false

0x60 = 0110 0000, so 2 bits will return true.

And you need to test with moving bit, so
0x1, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
I tried to do this and got the wrong result. But apparently my function of converting hex to bit was wrong, because I got it 10010110
I also tried version 0x1, 0x02, 0x04, 0x08, 0x16, 0x32, 0x64, 0x128. Apparently I do not quite understand how to properly convert to another type of display.
Tell me more. Does Mikrotik have a built-in function that would immediately print out the converted number from hex to bit?
Last edited by DyadyaGenya on Thu Jun 08, 2023 10:15 pm, edited 1 time in total.
 
holvoetn
Forum Guru
Forum Guru
Posts: 5472
Joined: Tue Apr 13, 2021 2:14 am
Location: Belgium

Re: To determine the value of each bit in a byte.

Thu Jun 08, 2023 10:13 pm

I also tried version 0x1, 0x02, 0x04, 0x08, 0x16, 0x32, 0x64, 0x128. Apparently I do not quite understand how to properly convert to another type of display.
True, it appears you have some homework on the basics of conversion between binary and hex :lol:
(damn, that's almost 40 years ago I learned that ...)

Tip: Windows calculator in programmer mode can help.
Or a stupid piece of paper. Write it down. Then you will see how it goes.
 
DyadyaGenya
Member Candidate
Member Candidate
Topic Author
Posts: 220
Joined: Mon May 08, 2023 10:34 pm

Re: To determine the value of each bit in a byte.

Thu Jun 08, 2023 10:17 pm

No, it appears you have some homework on the basics of conversion between binary and hex :lol:
(damn, that's almost 40 years ago I learned that ...)

Tip: Windows calculator in programmer mode can help.
Or a stupid piece of paper. Write it down. Then you will see how it goes.
I learned about this for about a week))) I haven’t fully mastered it yet))) And look at the request that I added above. While correcting the answer, you have already written your own.
 
holvoetn
Forum Guru
Forum Guru
Posts: 5472
Joined: Tue Apr 13, 2021 2:14 am
Location: Belgium

Re: To determine the value of each bit in a byte.

Thu Jun 08, 2023 10:18 pm

Tell me more. Does Mikrotik have a built-in function that would immediately print out the converted number from hex to bit?
viewtopic.php?p=965205#p965205

Offered by our house cat Rex.
 
optio
Long time Member
Long time Member
Posts: 672
Joined: Mon Dec 26, 2022 2:57 pm

Re: To determine the value of each bit in a byte.

Thu Jun 08, 2023 10:31 pm

For example, if the number is represented in hexadecimal as "0x60", in binary it would be "01100000". How can we determine the value of, let's say, the 2nd or 7th bit? Are there any built-in functions for this in MikroTik?
Shift n bits -1 right (bitwise >>) to get bit at position from right to left and check with bitwise & 1.
Examples:

To check: 01100000
> :local value 0x60
> :put (($value >> 1) & 1)
> 0
To check: 01100000
> :local value 0x60
> :put (($value >> 6) & 1)
> 1
 
DyadyaGenya
Member Candidate
Member Candidate
Topic Author
Posts: 220
Joined: Mon May 08, 2023 10:34 pm

Re: To determine the value of each bit in a byte.

Thu Jun 08, 2023 10:36 pm

Shift n bits -1 right (bitwise >>) to get bit at position from right to left and check with bitwise & 1.
Now I'm starting to understand your PDU reading code.
 
optio
Long time Member
Long time Member
Posts: 672
Joined: Mon Dec 26, 2022 2:57 pm

Re: To determine the value of each bit in a byte.

Thu Jun 08, 2023 10:42 pm

Shift n bits -1 right (bitwise >>) to get bit at position from right to left and check with bitwise & 1.
Now I'm starting to understand your PDU reading code.
Mostly is not mine :), it's taken from viewtopic.php?p=797583#p797583, but I understand enough to adapt it for my purpose.
 
DyadyaGenya
Member Candidate
Member Candidate
Topic Author
Posts: 220
Joined: Mon May 08, 2023 10:34 pm

Re: To determine the value of each bit in a byte.

Thu Jun 08, 2023 10:54 pm

but I understand enough to adapt it for my purpose.
I hope you understand that I recently started doing this))) And I would like to clarify. Should the shift start from 0 or from 1?
 
optio
Long time Member
Long time Member
Posts: 672
Joined: Mon Dec 26, 2022 2:57 pm

Re: To determine the value of each bit in a byte.

Thu Jun 08, 2023 10:57 pm

I hope you understand that I recently started doing this))) And I would like to clarify. Should the shift start from 0 or from 1?
0, because 1 (bit position) - 1 = 0
You don't need to shift with 0, just check with ($value & 1)

01100000
> :local value 0x60
> :put ($value & 1)
> 0
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: To determine the value of each bit in a byte.

Fri Jun 09, 2023 1:30 am

I felt nominated, here's a little gift....

based on:
viewtopic.php?p=965205#p965201

Obtain a bit value from a byte (expected input from 0x00 to 0xFF, and the wanted bits. If the bits number is not specified, convert all byte to bit.
0x can be omitted
:global getMyBitFromHex do={
    :local conv   $1
    :if (!($conv~"(^0x|^)[0-9a-fA-F]{2}\$")) do={:return "00000000"}
    :if ([:typeof [:find $conv "0x" -1]] = "nil") do={:set conv "0x$conv"}
    :local number [:tonum $conv]
    :local wanted [:tostr "$2"]
    :if ($wanted = "") do={:set wanted "87654321"}
    :local values [:toarray "x,0,0,0,0,0,0,0,0"]
    :local power 1
    :local output ""
    :for position from=1 to=8 step=1 do={
        :if ($number & $power) do={:set ($values->$position) 1}
        :set power ($power * 2)
        :if ([:len [:find $wanted $position]] > 0) do={
            :set output "$($values->$position)$output"
        }
    }
    :return $output
}
As wanted bit(s) can be specified one or more position.
Position is from 8 to 1.

examples code

[] > :put [$getMyBitFromHex "0xA8"]
10101000

[] > :put [$getMyBitFromHex "0xA8" 8]
1

[] > :put [$getMyBitFromHex "0xA8" 765]
010 <<== is 2

[] > :put [$getMyBitFromHex "0xA8" 4321]
1000 <<== is 8
no matter the specified bits order, or if is specified a wrong position or same time the same position.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: To determine the value of each bit in a byte.

Fri Jun 09, 2023 1:51 am

And another gift,

you provide the wanted bit set to 1 on the byte, and on out you have the wanted hex value
:global getMyHexFromBit do={

    :local 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
    }

    :local wanted [:tostr "$1"]
    :if ($wanted = "") do={:set wanted "87654321"}
    :local power  1
    :local output 0
    :for position from=1 to=8 step=1 do={
        :if ([:len [:find $wanted $position]] > 0) do={
            :set output ($output + $power)
        }
        :set power ($power * 2)
    }
    :return [$numbyte2hex $output]
}

examples code

[] > :put [$getMyHexFromBit 864]
A8

[] > :put [$getMyHexFromBit 246]
2A

[] > :put [$getMyHexFromBit 2]
02

[] > :put [$getMyHexFromBit 4]
08
no matter the specified bits order, or if is specified a wrong position or same time the same position.
 
DyadyaGenya
Member Candidate
Member Candidate
Topic Author
Posts: 220
Joined: Mon May 08, 2023 10:34 pm

Re: To determine the value of each bit in a byte.

Sat Jun 17, 2023 9:59 pm

Not quite on topic, but related.
Why can I print like this:
:put ( "\41" )
And get A.
And this is not how it works:
:local num 41
:put ( "\\$num"  )
And how can this be done?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: To determine the value of each bit in a byte.

Sat Jun 17, 2023 11:03 pm

(wrong assumptions from the author of previous post, read my next posts)
Last edited by rextended on Sat Jun 17, 2023 11:33 pm, edited 3 times in total.
 
DyadyaGenya
Member Candidate
Member Candidate
Topic Author
Posts: 220
Joined: Mon May 08, 2023 10:34 pm

Re: To determine the value of each bit in a byte.

Sat Jun 17, 2023 11:10 pm

:local num 41
:put [[:parse ":return \"\\$num\""]]
Thank you. I understand that this can only be done using the ":parse" command?
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: To determine the value of each bit in a byte.

Sat Jun 17, 2023 11:16 pm

Otherwise I wouldn't have written it that way....

There is no function that converts a hex to a character,
otherwise I wouldn't have written my own functions... also including this...
You'd better take a look...
viewtopic.php?f=9&t=108127&p=871741#p871741
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: To determine the value of each bit in a byte.

Sat Jun 17, 2023 11:25 pm

Thank you. I understand that this can only be done using the ":parse" command?
One moment, do not do confusion...

\xx is supposed to be a hexadecimal number, not a decimal number, do not call the var "num", call it "hex"
you continuosly confuse the number base...

0x41 is 65, so that way can not be used to print decimal "41" as character.
41 on hex is 0x29 and the correct character is the )

If you really want convert HEXADECIMAL number 0x41 to a character "A":
:local hex "41"
:put [[:parse ":return \"\\$hex\""]]

If you really want convert DECIMAL number 41 to a character ")":
:local num 41

:local 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
}

:put [[:parse ":return \"\\$[$numbyte2hex $num]\""]]
 
holvoetn
Forum Guru
Forum Guru
Posts: 5472
Joined: Tue Apr 13, 2021 2:14 am
Location: Belgium

Re: To determine the value of each bit in a byte.

Sun Jun 18, 2023 11:39 am

One moment, do not do confusion...

\xx is supposed to be a hexadecimal number, not a decimal number, do not call the var "num", call it "hex"
you continuosly confuse the number base...
Ah, things haven't changed after a week off :lol:
 
DyadyaGenya
Member Candidate
Member Candidate
Topic Author
Posts: 220
Joined: Mon May 08, 2023 10:34 pm

Re: To determine the value of each bit in a byte.

Sun Jun 18, 2023 2:35 pm

If you really want convert DECIMAL number 41 to a character ")":
:local num 41

:local 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
}

:put [[:parse ":return \"\\$[$numbyte2hex $num]\""]]
Just something similar to the best of my knowledge and tried to do. That's why the question arose why the symbol does not print.
:local nums 65
:local res ""
:local res1 ""

:for i from=7 to=4 do={
    :set res ($res.(($nums >> $i) & 1) )
}
:set res [ :pick "0123456789ABCDEF"  ( ( [ :tonum $res ] ) & 0xF) ]

:for i from=3 to=0 do={
    :set res1 ($res1.(($nums >> $i) & 1) )
}
:set res1 [ :pick "0123456789ABCDEF"  ( ( [ :tonum $res1 ] ) & 0xF) ]

:set res ($res.$res1)
:put [[:parse ":return \"\\$res\""]]
Only yesterday I didn’t succeed for one moment (printing), and today I tried to sort through all the characters from this table https://upload.wikimedia.org/wikipedia/ ... e-wide.svg, but not all are printed.
And your way prints
 
DyadyaGenya
Member Candidate
Member Candidate
Topic Author
Posts: 220
Joined: Mon May 08, 2023 10:34 pm

Re: To determine the value of each bit in a byte.

Mon Jun 19, 2023 4:48 pm

0x41 is 65, so that way can not be used to print decimal "41" as character.
41 on hex is 0x29 and the correct character is the )
Can you tell me where is the error in my code? And here the question is not whether I want or do not want to leave my code. You were interested in what exactly I wanted to print, I showed my train of thought, how I came to
:local num 41
:put ( "\\$num"  )
I understand that I was moving somewhere in the right direction, and I already understand your code, but I wanted to understand my mistake.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: To determine the value of each bit in a byte.

Mon Jun 19, 2023 5:45 pm

Why you for do 2 + 4 = 6
instead you do x1 = 2 / 2, x2 = 4 / 2, result = (x1 + x2) * 2 = 6
??????????????

:put ( "\\$num" ) = print on screen the character "\" (and since is the escape character, must be writed twice) followed with the value of variable called "num"


As already wroted dozen of times, RouterOS do not DIRECTLY support non-7-bit-ascii characters...

The same without convert the num to hex:
{
:local num 65
:local charsString ""
:for x from=0 to=15 step=1 do={ :for y from=0 to=15 step=1 do={
    :local tmpHex "$[:pick "0123456789ABCDEF" $x ($x+1)]$[:pick "0123456789ABCDEF" $y ($y+1)]"
    :set $charsString "$charsString$[[:parse "(\"\\$tmpHex\")"]]"
} }
:put [:pick $charsString $num ($num +1)]
}
 
DyadyaGenya
Member Candidate
Member Candidate
Topic Author
Posts: 220
Joined: Mon May 08, 2023 10:34 pm

Re: To determine the value of each bit in a byte.

Tue Jun 20, 2023 6:12 pm

Why you for do 2 + 4 = 6
instead you do x1 = 2 / 2, x2 = 4 / 2, result = (x1 + x2) * 2 = 6
??????????????
To be honest, I didn't do either.
:put ( "\\$num" ) = print on screen the character "\" (and since is the escape character, must be writed twice) followed with the value of variable called "num"
I tried both options, but this one seemed more correct to me. Yes, and you seem to be using it
\"\\$
As already wroted dozen of times, RouterOS do not DIRECTLY support non-7-bit-ascii characters...
I did not think to immediately recode from GSM. I just tried to print the table
The same without convert the num to hex:
{
:local num 65
:local charsString ""
:for x from=0 to=15 step=1 do={ :for y from=0 to=15 step=1 do={
I don't understand why 15?
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 3422
Joined: Sun May 01, 2016 7:12 pm
Location: California

Re: To determine the value of each bit in a byte.

Tue Jun 20, 2023 6:48 pm

I don't understand why 15?
15 dec (base 10) is "F" in hex (base 16), 00001111 in binary (base 2) and "\0F" as a Mikrotik string... Maybe a chart will help:

Image

(from Google: https://web.alfredstate.edu/faculty/wei ... index.html )
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12001
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: To determine the value of each bit in a byte.

Tue Jun 20, 2023 6:54 pm

I don't understand why 15?
because the hex Byte go from 00 to FF, and 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F are 16 characters, but the index start from 0, so are 16 indexed numbers, from 0 to 15

Who is online

Users browsing this forum: eworm, malks and 24 guests