Bits, Bytes and Bitwise Operations
Ever wondered what it's like to write bitwise operations from scratch? Neither did I... until recently when I found them very useful for doing cryptographic hashes. Of course, to better internalize these concepts... I wrote them from scratch. I could've potentially have written them in Assembly or Binary, that would've been far easier. In that case though, that defeats the purpose of learning how to do it in an imperative language... Since most of my work is in an imperative (sometimes functional) paradigm.
Let's observe the bitwise operations possible with any bit based endian structure.
1. AND (&) - Returns ones for each bit in a comparison of two endian structures that both have ones at the same position.
2. OR (|) - Returns ones for each bit in a comparison of two endian structures that atleast has one one at the same position.
3. XOR (^) - Returns ones for each bit in a comparison of two endian structures that either one has a one but not both at the same position.
4. Left Shift (<<) - Shifts the first endian structure N amount of bits to the left based on the integer value of the second value, creating zeroes in their original place.
5. Right Shift [Sign-Propagating] (>>) - Shifts the first endian structure N amount of bits to the right based on the integer value of the second value, also discarding bits shifted off.
6. Right Shift [Zero-Fill] (>>>) - Shifts the first endian structure N amount of bits to the right based on the integer value of the second value, also discarding bits shifted off while also creating zeroes in their place.
7. Not (~) - Inverts the endian data structure, can only be used on one data structure at a time.
These seem pretty self explanatory to anyone with fair bit of experience in Computer Science... Let's ask some rudimentary questions first though about our experiment.
Bitwise and 32 bit Endianess...
Typically Bitshifts are done assuming 32 bit Endian structures in JS... However, in the case of my experiment. I enable any sized endian structure to work a bitshift. This is merely just for flexibility purposes and allowing left and right shifts greater then the original endian data structure, causing it to be zero in all edge cases where N > then the original data structure in left shifts and zero fill right shifts and 1 when dealing with sign propagating right shifts dealing with negative numerical values.
Two Right Shifts? Why?
The difference between Sign Propagating and Zero Fill Right Shifts is that Zero-Fill Shifts always produce a positive number (assuming any numerical endian structure). Sign propogating preserves the leftmost bits value (1 or 0) and reproduces it for each respective value thereafter. These two distinct bit shifts were created in the case scenario of preserving negative numerical values when rotating bits around.
Now for some code! Yay!
Hope you learned something! If you want to review the repository with Unit Tests included check this repository out. I'll be posting about Emoji Cryptographic Hashes tomorrow!