I have a ACLs system previously built by someone else and I am trying to understand how bit-masking works there. I have this 4 constants defined:
const NONE = 0;
const READ = 1;
const WRITE = 2;
const UPDATE = 4;
const DELETE = 8;
Then in DB I am seeing users with permissions like 1, 2, 5, 9, 15. I have tried to transform them using this tool and I end up with this result:
0 // NONE
1 // READ
2 // WRITE
3 // UPDATE|DELETE
4 // UPDATE
5 // WRITE|DELETE
6 // WRITE|UPDATE
7 // WRITE|UPDATE|DELETE
8 // DELETE
9 // READ|DELETE
10 // READ|UPDATE
11 // READ|UPDATE|DELETE
12 // READ|WRITE
13 // READ|WRITE|DELETE
14 // READ|WRITE|UPDATE
15 // READ|WRITE|DELETE|UPDATE
How I think this work is as follow:
Decimal Hexadecimal
3 00000011
Because the two last bits are 1 I am assuming that those users having 3 will have UPDATE|DELETE permissions (see table above). Is that right? If not what's the right way to translate from decimal to bit-mask?
0 = NONE is a special case which can be checked by simple comparison.
If you want to ask the question is constant cn with the value of 2^(n-1) set, then we do this with (1 = yes, 0 = no, % = modulo):
(value / cn) % 2
If we want to get all flags that are set, you can do this with the following pseudo code:
c := 1
while value > 0
if value % 2 = 1
// constant c is set
...
end if
value := value / 2
c := c * 2
end while
Related
I'm trying to do something relatively simple with the Arduino (trying to get some lights to light up like a Simon says game) but I'm getting some really bizarre outputs
I got some really bizarre output on the pins so I took those parts of the code out to see it on a serial monitor to see what the contents of the array that holds the sequence of lights (colors) are. It just really doesn't make sense to me.
What my code is supposed to do is append a random number from 1-4 onto colors[] and then read them back out onto the serial monitor
bool lightValue[4] = { 0 };
// stores whether each LED is lit or not
int buttonPressed;
// 0 - no button pressed / nothing
// 1 - red
// 2 - yellow
// 3 - green
// 4 - blue
int colors[] = { 0 };
// probably not the best name for this variable but oh well
// stores all the colors displayed for the simon says
// refer above to see what each number means
int colorNum = 0;
// again not the best name, stores the number of colors displayed so far
// AKA the length of colors[]
int randomNum;
// will store a random number
// variables
void setup() {
randomSeed(analogRead(0));
Serial.begin(9600);
Serial.println();
Serial.println("PROGRAM START");
}
// pinModes. Lots of pinModes.
void loop() {
randomNum = random(1,5);
colors[colorNum] = randomNum;
Serial.println();
Serial.print(colorNum);
Serial.print(" ");
colorNum++;
// adds another random color onto the end of the color sequence
for (int i = 0; i < colorNum; i++) {
Serial.print(colors[i]);
delay(500);
}
}
Some examples of outputs I got:
0 3
0 1
2 13520
3 145202
4 1552024
5 16520241
6 175202414
7 1852024141
8 19520241414
9 1105202414141
10 11152024141414
0 1
2 13520
3 145202
4 1552024
5 16520241
6 175202414
7 1852024141
8 19520241414
9 1105202414141
10 11152024141414
colorNum, the main increment of this loop for some reason skips over one. The first and second output do not match, the third item in the array is 520, and for some reason, the second item is incrementing by 1 every step. Also, it stops at 10 for some reason.
The only thing I could chalk this inconsistent behavior to is accessing some piece of memory where it shouldn't, but I can't come up for the life of me where I horribly messed up.
int colors[] = { 0 };
defines an integer array with a single element 0.
Here colors[colorNum] = randomNum; you're assigning numbers to indices outside of that array for colorNum > 0. You shouldn't do that. This memory region is not reserved for colors!
So who stops your compiler from storing colorNum right after colors?
So when you assing a value to colors[1] you could very well change the value of colorNum. Same for your loop control variable i.
So the second value is incremented because you're incrementing colorNum which is at the same memory location as colorNum[1].
The print for colorNum == 1 is missing because you assigned 5 to colors[2] which is at the same memory location as your loop control variable i. As 5 > colorNum the loop does not run.
I just did this on a 32bit C++ compiler:
int colors[] = {0};
int colorNum = 0;
int i = 0;
And the addresses printed:
colors[0] # 0x7fff029a5ac4
colorNum # 0x7fff029a5ac8
colors[1] # 0x7fff029a5ac8
i # 0x7fff029a5acc
colors[2] # 0x7fff029a5acc
Note that colorNum is just 4 bytes after colors[0] which is the same address as colors[1]!
Anyway you shouldn't just fill memory in an infinite loop in the first place.
You're on a micro controller where memory is a limited resource
When executing:
def guess(a..b) do
IO.puts "In rn = #{a}..#{b}"
guess(a..b, IO.getn("Is it greater than #{div(a + b, 2)} ? : ", 1) |> String.upcase == "Y")
end
def guess(a..b, true) do
guess(div(a + b, 2)..b)
end
def guess(a..b, false) do
guess(a..div(a + b, 2))
end
Results:
iex(1)> Test.guess(1..10)
1 In rn = 1..10
2 Is it greater than 5 ? : y
3 In rn = 5..10
4 Is it greater than 7 ? :
5 In rn = 5..7
6 Is it greater than 6 ? : n
7 In rn = 5..6
8 Is it greater than 5 ? :
9 In rn = 5..5
10 Is it greater than 5 ? : y
11 In rn = 5..5
12 Is it greater than 5 ? :
13 In rn = 5..5
14 Is it greater than 5 ? :
iex did not wait for user input on lines 4, 8, & 12 - after receiving an input, it appears to run through the loop twice.
Why might that be?
Solved:
Apparently, something weird happens with IO.getn when used in this manner - perhaps reading "Y" as a byte, and "enter" as a separate byte. Replacing IO.gets and no character count seems to fix the problem. Alternatively, isolating the getn method call might keep this issue from occurring.
You are correct. When in the terminal, IO.getn/1 only returns the bytes after you enter a new line, which means if you are reading byte per byte recursively, you are going to receive two bytes, one for the user command and another for the new line. IO.gets/1 is the way to go here.
Is there an existing function where we can pop a (key,value) pair from a map in GO? I use the word pop instead of remove because a pop would re-arrange the elements after the index where the (key,value) was removed.
As an example the following code:
package main
import "fmt"
func main() {
mapp := make(map[int]int)
fmt.Println("before removal:")
for i := 1; i < 7; i++ {
mapp[i] = i
}
fmt.Println(mapp)
delete(mapp, 2)
fmt.Println("\nafter the removal:")
for i := 1; i < 7; i++ {
fmt.Println(i, mapp[i])
}
}
Produces the following output:
before removal:
map[1:1 2:2 3:3 4:4 5:5 6:6]
after the removal:
1 1
2 0
3 3
4 4
5 5
6 6
We notice that index location 2 is empty. I would like the output to be the following:
before removal:
map[1:1 2:2 3:3 4:4 5:5 6:6]
after the removal:
1 1
2 3
3 4
4 5
5 6
Is this functionality already in Go or would I have to implement it?
I think that you are misunderstanding what a map is and how it works. You should not see it as an "array with gaps", but as a classic hash table.
And to answer your question, when you use delete(), the value is deleted from the map, the problem is how you iterate over the "values" of the map.
To help you understand:
mapp := make(map[int]int)
fmt.Println(2, mapp[2])
will print
2 0
Why ? Simply because when the requested key doesn't exist, we get the value type's zero value. In this case the value type is int, so the zero value is 0.
So, you want to see if a key exists in the map before printing it and you have to use two-value assignment, like that:
for i := 1; i < 7; i++ {
if value, exists := mapp[i]; exists {
fmt.Println(i, value)
}
}
and it will print
1 1
3 3
4 4
5 5
6 6
Not really what you want, but the closer you can get directly with maps.
You can have a look at this blog post for more information and examples.
If you really want to have an array where you can remove values, see Verran's answer and use slices instead.
From the Go documentation:
When iterating over a map with a range loop, the iteration order is not specified and is not guaranteed to be the same from one iteration to the next.
From this, it follows that there would be no way to automatically move a value up one position to fill a gap, since the key can be in a different iteration position each time you look at the values and theres no guarantee that the value mapped to 2 will slide up to 1.
If you want to do something like this, you will have to manually shift everything down one key value, something like:
for key := 2; key < len(map)-1; key++ {
map[key] = map[key+1]
}
Alternatively, you could use slices and if you know the index you need to "pop", create a new slice that omits the value:
value := slice[2]
slice = copy(slice[:2], slice[2+1:])
I get an 16 Bit integer from C. This integer consists of 16 flags.
How can I convert this integer in a record of 16 booleans?
Thanks!
type Flags is record
Flag1 : Boolean;
Flag2 : Boolean;
- ...
Flag15 : Boolean;
end record;
for Flags use record
Flag1 at 0 range 0 .. 0;
Flag2 at 0 range 1 .. 1;
-- ...
Flag15 at 0 range 15 .. 15;
end record;
for Flags'Size use 16;
-- This is vital, because normally, records are passed by-reference in Ada.
-- However, as we use this type with C, it has to be passed by value.
-- C_Pass_By_Copy was introduced in GNAT and is part of the language since Ada 2005.
pragma Convention (C_Pass_By_Copy, Flags);
You can use this type directly in the declaration of the imported C function instad of the C integer type.
You can just simply perform 16 right bit shifts and bitwise AND the result with 1 to determine whether or not a bit/flag is set. Here's an example (I'm hoping this isn't homework):
#include <stdio.h>
#include <stdint.h>
typedef unsigned char BOOL;
int main(void)
{
unsigned i;
uint16_t flags = 0x6E8B; /* 0b0110111010001011 */
BOOL arr[16];
for (i = 0; i < 16; i++) {
arr[i] = (flags >> i) & 1;
printf("flag %u: %u\n", i+1, arr[i]);
}
return 0;
}
arr[0] will contain the least significant bit, and arr[15] the most significant.
Output:
flag 1: 1
flag 2: 1
flag 3: 0
flag 4: 1
flag 5: 0
flag 6: 0
flag 7: 0
flag 8: 1
flag 9: 0
flag 10: 1
flag 11: 1
flag 12: 1
flag 13: 0
flag 14: 1
flag 15: 1
flag 16: 0
In Ada, you can usually declare an imported function to take parameters or return values of the type you want, rather than a C-equivalent type which you then have to convert.
So, here, you want
type Flags is array (0 .. 15) of Boolean;
for Flags'Component_Size use 1;
for Flags'Size use 16;
pragma Convention (C, Flags);
and you can declare your function as
function Get_Flags return Flags;
pragma Import (C, Get_Flags, “get_flags");
which with
unsigned short get_flags(void) {
return 0x6e8b;
}
and a simple harness gave me
flag 0 is TRUE
flag 1 is TRUE
flag 2 is FALSE
flag 3 is TRUE
flag 4 is FALSE
flag 5 is FALSE
flag 6 is FALSE
flag 7 is TRUE
flag 8 is FALSE
flag 9 is TRUE
flag 10 is TRUE
flag 11 is TRUE
flag 12 is FALSE
flag 13 is TRUE
flag 14 is TRUE
flag 15 is FALSE
As Bo Persson noted, this is fine so long as your code only needs to run on a little-endian machine. If you want it to run on a SPARC or a Powerbook, it’s probably best to use trashgod’s suggestion;
subtype Flags is Interfaces.C.unsigned_short;
use type Flags;
function Get_Flags return Flags;
pragma Import (C, Get_Flags, "get_flags");
and then, probably, name your flag bits (with something more meaningful!)
Flag_3 : constant Flags := 2#0000_0000_0000_1000#;
or (probably more like the C)
Flag_4 : constant Flags := 2 ** 4;
and then check
(Get_Flags and Flag_3) /= 0
In Ada, a modular type allows logical operations to access a value as a bit set. Introduced in Ada 95, an overview may be found in the Ada 95 Rationale, §3.3.2 Modular Types. Depending on implementation, the pre-defined type Interfaces.C.unsigned_short my be a convenient choice for obtaining the value from C.
You can also use overlaying to achieve the desired result; let's assume that these booleans are all meaningful and strictly boolean (i.e. nothing that's an enumeration).
First you need to define your record; I'm going to be using a single Nybble to illustrate, but the principle is applicable. The Nybble is the old DOS attributes: reading (visibility-wise; should be Is_Hidden, in retrospect), write, archive, and system.
Type Nyble_Data is mod 2**4;
For Nyble_Data'Size use 4;
Type Data_Record is record
Can_Read, Can_Write, Is_Archived, Is_System : Boolean:= False;
end record;
-- Ensure 4 bits used.
pragma Pack (Data_Record);
For Data_Record'Size use 4;
-- Specify Layout.
For Data_Record use
record
Can_Read at 0 range 0..0;
Can_Write at 0 range 1..1;
Is_Archived at 0 range 2..2;
Is_System at 0 range 3..3;
end record;
-- This is where the magic occurs.
Function Convert( Data : In Nyble_Data ) Return Data_Record is
Result : Data_Record;
For Result'Address use Data'Address;
Pragma Import( Convention => Ada, Entity => Result );
Pragma Inline( Convert );
begin
Return Result;
end Convert;
-- Test variables.
Input : Nyble_Data:= 5;
Output : Data_Record:= Convert(Input);
-- Display the record.
Procedure Put( Data : In Data_Record ) is
Use Ada.Text_IO;
begin
Put_Line( "Read: " & ASCII.HT & Boolean'Image(Data.Can_Read) );
Put_Line( "Write: " & ASCII.HT & Boolean'Image(Data.Can_Write) );
Put_Line( "Archive:" & ASCII.HT & Boolean'Image(Data.Is_Archived) );
Put_Line( "System: " & ASCII.HT & Boolean'Image(Data.Is_System) );
end Put;
You can use a union containing a short int (or a int_16) and a bit field:
union UMyFlags {
short n;
struct {
flag_1 : 1;
flag_2 : 1;
// other flags ...
} flags;
};
However, because of byte ordering, your code will not be portable on every platform.
Let's say that I have the following number: 1286 now I want to remove the last digit 6 and end up with the first 3 digits 128 only. I also would like to do this using the number 6 and the number 1286 only as inputs.
Also if there is a c# solution would be great.
Thanks
Edit:
I want to do this using a math equation between the 6 and the 1286, I already know how to parse strings, which is not what I'm after.
please try the below code: (this is done only using mathematical functions, also I don't know C#)
java.util.Scanner s=new java.util.Scanner(System.in);
int last=s.nextInt();
int firstNumber=s.nextInt();
int ans=0;
loop:
for(int temp=firstNumber,i=0;temp>0;temp/=10)
{
if(temp%10==last){ans=temp/10;while(i>0){ans=ans*10+(i%10);i/=10;} break loop;}
i=i*10;
i=i+(temp%10);
}
if(ans>0)System.out.println(ans);
}
}
string input = "OneTwoThree";
// Get first three characters
string sub = input.Substring(0, 3);
sub will now have the first 3 chars from the string, the 0 is the start pos, and then how many chars do you want (ie: 3) - this is where the (0, 3) come in to it - if you had (3, 3), sub would equal "Two"
I think this might be what you are looking for :)
In JavaScript: Here is your number:
var num = 1286;
This line removes the last digit:
num % 10; //returns 6
And these two lines remove the 6:
num /= 10 // turns num to 128.6
num = Math.trunc(num) // num now equals 128
Better yet, you could put it in a function, like so:
function sumOfDigits(num) {
const sumArr = [];
while (num > 0) {
sumArr.push(num % 10);
num /= 10;
num = Math.trunc(num);
}
return sumArr.reduce((a, b) => a + b, 0);
}
sumOfDigits(1234);
// returns 10
Hope this helps.