Tweak

InsaneJournal

Tweak says, "Mr. Frodo!"

Username: 
Password:    
Remember Me
  • Create Account
  • IJ Login
  • OpenID Login
Search by : 
  • View
    • Create Account
    • IJ Login
    • OpenID Login
  • Journal
    • Post
    • Edit Entries
    • Customize Journal
    • Comment Settings
    • Recent Comments
    • Manage Tags
  • Account
    • Manage Account
    • Viewing Options
    • Manage Profile
    • Manage Notifications
    • Manage Pictures
    • Manage Schools
    • Account Status
  • Friends
    • Edit Friends
    • Edit Custom Groups
    • Friends Filter
    • Nudge Friends
    • Invite
    • Create RSS Feed
  • Asylums
    • Post
    • Asylum Invitations
    • Manage Asylums
    • Create Asylum
  • Site
    • Support
    • Upgrade Account
    • FAQs
    • Search By Location
    • Search By Interest
    • Search Randomly

Alis Dee ([info]loqia) wrote,
@ 2006-09-28 12:36:00

Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Entry tags:code girl, geeking:compsci 101, mysql, programming:bitmask, programming:php, tutorials

Bitmasking 101

I totally did bitmasked permissions in sk.log yesterday; it’s something I’ve been putting off pretty much since I first started writing the damn thing, but have never gotten around to doing because I didn’t really understand the maths behind it. Some back story; there are four levels of permission for all items (mainly posts and comments) at sk.log. There’s an ‘open’ permissions, viewable by everyone, a ‘closed’ permission viewable by no-one (except the site admin and the item author) and a registered-only permission viewable by, well, registered users only. I always knew I wanted to drill down the registered only into a LiveJournal-style system of groups, and I always wanted to do it with bitmasks (rather than an extra database table). I always knew ‘visually’ how bitmasks work. So say you have a a mask of 00000, now pretend that each of those zeroes is one ‘group’. Say I want to ’set’ groups 1, 3 and 4; ie. these groups will be able to view a particular post, etc. That would then look like 11010 (going right-to-left starting at 0). 11010 in decimals is 26 (2^1 + 2^3 + 2^4), which is the bitmask number. If I have a personal bitmask of 00110 (2^1 + 2^3 = 6), then I can compare the two like so:

11010
00110
=====
00010

Because both have a 1 in the same column, then the mask ‘matches’ and I have permission to see… whatever it is I’m seeing.

Unfortunately, I had no idea how to do this in code.

Luckily for me, it’s really, really easy! No-one ever uses logical AND or OR (& and | respectively), but that’s what they’re there to do. A logical OR will give you the ‘combination’ of two binary numbers:

01011 |
10000
=====
11011

Whereas a logical AND will give you the ‘overlap’ of the two:

01011 &
10001
=====
00001

Obviously, logical AND is the awesome, no-thinking-involved choice for comparing bitmasks. If the result of a logical AND between two numbers is greater than zero, then they ‘match’. The OR comes in handy, too. I’m not exactly sure why, but I’ve read that, when forming a bitmask, you should use logical OR as opposed to addition.

The really funky part of bitmasking is that you can also use it in MySQL queries:

( Cut for code… )

It should be noted that doBitmask is a ‘lazy’ function and doesn’t check for valid input. Feeding it non-integers will give you a result of 1. The other thing is that, with bitmasking, there are a finite number of groups (’bits’) that you can have in any one system. It’s probably going to be either 16 (ie. 0,..,15) or 32 (0,…,31); this is a limitation of the underlying computer or language architecture with how many bits it uses to define an integer.

Comment?

This post has been mirrored from void-star.net β. You may comment there using your LiveJournal/Dreamwidth/OpenID URL instead of an email address. Randoms and lurkers are more than welcome.




Home | Site Map | Manage Account | TOS | Privacy | Support | FAQs