🚩 Bitwise flags are amazing, and you should use them
Tags: mathematics, database, softwareengineering, optimisation
Published: 2023-01-21 13:56:35

[**Original post**](https://krypton.ninja/Bitwise-flags-are-amazing-and-you-should-use-them)

If you are making a web application with users management, bitwise flags will be really useful for that same application. I've never used bitwise flags in my past small web application, and I definitely regret not having used them before... Not only it's super convenient, but you also don't need tons of rows in your database to store various account information. I'm using bitwise flags in [Project Absence](https://github.com/ProjectAbsence) as well, hence this blog post explaining how it works!

> _PS: This will most likely be my **last blog post focused on software engineering**, I will focus more on **cyber security** in the future, as this was the main goal of my blog when I created it..._

## Operators Refresh
Before jumping into what bitwise flags are and how to use them, it's needed to get to know the **three** operators that will be used.

### `OR` Operator
The `OR` - I will also use `|` - is a basic operator that you most likely have already used while coding. Here's a small refresh on the result of an `OR` operation:

| A | B | A OR B |
|---|---|--------|
| 0 | 0 |    0   |
| 0 | 1 |    1   |
| 1 | 0 |    1   |
| 1 | 1 |    1   |

### `AND` Operator
Similar to the `OR` operator, the `AND` - I will also use `&` - operator is a basic operator you most likely have already used. Here's the table as well:

| A | B | A AND B |
|---|---|---------|
| 0 | 0 |    0    |
| 0 | 1 |    0    |
| 1 | 0 |    0    |
| 1 | 1 |    1    |

### Left Shift Operator
The left shift - I will also use `<<` - operator is an operator you may have not used yet. For bitwise flags it is one of the base that is needed to make it working. Let's take a look at how it works, it's really easy.

Let's take as example `1 << 4`:

- We first write down `1` as binary, which is obviously `0000 0001`
- We then move that entire binary number by `4` to the left, so we are left with `0001 0000`

Easy, right...? Here's a different way of showing it off:
```
0000 0001 << 4:
1. 0000 0010
2. 0000 0100
3. 0000 1000
4. 0001 0000
```

So `1 << 4` is equals to **16**. Yes, we can definitely write that down, though it gets more readable to use left shifts once you're dealing with big numbers such as `1 << 23` as you may not know that `8388608` actually represents this...

## How do bitwise flags work?
> *All those operators are very wonderful, but what are actually bitwise flags...?*

Well, very simple. It's a way to have many ON/OFF toggles in a single number. Let's quickly show that off with an example, you will also see how the `OR` and left shift operators will be used.

```go
package main

import "fmt"

// Set some user account flags
const (
    EMAIL_VERIFIED = 1 << 0
    ACCOUNT_BANNED = 1 << 1
)

// Create the Account structure
type Account struct {
    Username string
    Email    string
    Flags    int // Here there will be all account flags, e.g. whether the account is currently banned
}

// We create the function to check if the account is banned
func (a *Account) IsBanned() bool {
    return (a.Flags & ACCOUNT_BANNED) == ACCOUNT_BANNED
}
```

Now the, maybe, big question: *"How does this even work???"*

### Check if flag exists
Well, checking if a flag is existent is very simple. Considering we always use `1 << X`, when performing the left shift we will always and only move a binary **1** around. Then checking for a flag is as simple as using the `AND` operator. Let's suppose the user's account `Flags` field is **`18`**.

```
18              =>              0001 0010
ACCOUNT_BANNED  => 1 << 1 =>    0000 0010

0001 0010
0000 0010 AND
-------------
0000 0010       -> This is equals to ACCOUNT_BANNED
```

Hopefully with that example above you now understand why `(a.Flags & ACCOUNT_BANNED) == ACCOUNT_BANNED` can be used to check if a flag is existing.

### Creating the `a.Flags` value
To create the value that will be needed to be stored in `a.Flags` is also very simple. Let's suppose our account is both **verified** and **banned**, our flag will need to contain both of these values.

```
EMAIL_VERIFIED  => 1 << 0 =>    0000 0001
ACCOUNT_BANNED  => 1 << 1 =>    0000 0010

0000 0001
0000 0010 OR
------------
0000 0011
```

Now you most likely understand why the pattern is using **1** and not some other number in `1 << X`, other numbers may overwrite other flags. Now we convert `0000 0011` to decimal and we get **`3`** - that is the value for `a.Flags`. We can always add new flags with `newValue = oldValue | flag`.

## Why and where to use bitwise flags?
Now I understand that the explanation above is not the best, I may edit the post based on comments to clarify some things if needed - but maybe with some examples when bitwise flags may be useful, you may understand it better.

### Roles
#### Without bitwise flags
Let's suppose you need roles in your web application, totally understandable. How would you do it?

Maybe an `ENUM` field in your database if an account can only have **one** role. But what if it can have **more than one**? Maybe create a table `roles` that looks like the following:

| user_id | administrator | moderator | member |
|:-------:|:-------------:|:---------:|:------:|
|   1337  |       1       |     1     |    1   |
|   7331  |       0       |     1     |    1   |
|   7337  |       0       |     0     |    1   |

You get where this is going... Horrible table with just a row per role, yikes.

#### With bitwise flags
With bitwise flags, you just need a single row `roles` in your user's table :) Then you assign for every role a left shift operation:

```go
const (
    ADMINISTRATOR = 1 << 0
    MODERATOR     = 1 << 1
    MEMBER        = 1 << 2
)
```

After that use the techniques above to create the value for `roles`, for the user **7331** for example: `roles = MODERATOR | MEMBER`. Then we can check if a user is an administrator with something like that:

```go
func (u *User) IsAdministrator() bool {
    return (u.Roles & ADMINISTRATOR) == ADMINISTRATOR
}
```

Same goes for other account flags as shown above, to know if an account has the email verified or if they are banned.

### Permissions
Same as roles, if you need different users to have permissions on different functionalities of your web application, it may be totally worth it using bitwise flags.

### Remove unnecessary functions
Now this one may not be the biggest strength of bitwise flags, but it can definitely be used to optimize some **functions** in your code. Yes, functions.

#### Without bitwise flags
Let's imagine we want to print some information about a human:

```go
package main

import "fmt"

type Human struct {
    Firstname string
    Lastname  string
    Username  string
    Email     string
    Age       int
}

func (h *Human) PrintData() {
    fmt.Println("Firstname:", h.Firstname, "Lastname:", h.Lastname, "Username:", h.Username, "Email:", h.Email, "Age:", h.Age)
}

func main() {
    myHuman := &Human{
        Firstname: "John",
        Lastname:  "Doe",
        Username:  "jdoe",
        Email:     "john@doe.com",
        Age:       1337, // Yes that human it quite old...
    }
    myHuman.PrintData()
}
```

Now this works, as we get the expected output. But what if we want to print a single field? What if you don't want to print all of the fields? Well, yes you can do the following for **all** of your fields

```go
func (h *Human) PrintFirstname() {
    fmt.Println("Firstname:", h.Firstname)
}
```

But here again, what if you want only **3** of them? Well, you can replace `Println` to `Print` and **call the 3 functions** to print those fields. But cool kids use bitwise flags 🎉

#### With bitwise flags
Here again, assign each field a left shift operation and we copy the structure of above:

```go
package main

import "fmt"

type Human struct {
    Firstname string
    Lastname  string
    Username  string
    Email     string
    Age       int
}

const (
    FIRSTNAME = 1 << 0
    LASTNAME  = 1 << 1
    USERNAME  = 1 << 2
    EMAIL     = 1 << 3
    AGE       = 1 << 4
)
```

And now we can create the function needed to print each field, depending on the parameter - the **flags** - we give to the function.

```go
func (h *Human) PrintDataWithFlag(flags int) {
    // The " " at the end is just to make sure it looks good when printing multiple things
    if (flags & FIRSTNAME) == FIRSTNAME {
        fmt.Print("Firstname: ", h.Firstname, " ")
    }
    if (flags & LASTNAME) == LASTNAME {
        fmt.Print("Lastname: ", h.Lastname, " ")
    }
    if (flags & USERNAME) == USERNAME {
        fmt.Print("Username: ", h.Username, " ")
    }
    if (flags & EMAIL) == EMAIL {
        fmt.Print("Email: ", h.Email, " ")
    }
    if (flags & AGE) == AGE {
        fmt.Print("Age: ", h.Age, " ")
    }
}
```

Now what if we want to just print the `Firstname`, the `Email` and the `Age` fields? Very simple:

```go
func main() {
    myHuman := &Human{
        Firstname: "John",
        Lastname:  "Doe",
        Username:  "jdoe",
        Email:     "john@doe.com",
        Age:       1337, // Yes that human it quite old...
    }
    myHuman.PrintDataWithFlag(FIRSTNAME | EMAIL | AGE)
}
```

Now we have a clean way of printing all the **3** fields, without calling a **different function 3** times. You can see the full code [here](https://go.dev/play/p/YDGx-eGEt8T).

## Conclusion
If you've mangaged to read and understand all the way down until here and haven't given up on my poor explanation, congrats! Bitwise flags are somewhat complicated for newcomers but also easy once you understood the basics of it and where/how to use them. I personally use bitwise fields for **roles** and **account flags** in [Project Absence](https://github.com/ProjectAbsence). I don't really like having multiple rows in my datbase just to store such information, I'd rather have a single `fields` row.