├── .gitignore ├── LICENSE ├── README.md ├── bin └── build │ ├── clean.js │ ├── images.js │ ├── meta.js │ ├── styles.js │ ├── sync.js │ ├── views.js │ └── watch.js ├── docs ├── assets │ ├── images │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ └── switch.jpg │ └── styles │ │ └── main.css ├── index.html └── manifest.json ├── gulpfile.js ├── package-lock.json ├── package.json └── src ├── design └── favicons.ai ├── images ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-96x96.png └── switch.jpg ├── meta └── manifest.json ├── styles ├── 00-settings │ ├── _branding.scss │ ├── _generic.scss │ ├── _layout.scss │ └── _typography.scss ├── 01-tools │ ├── _breakpoint.scss │ └── _golden-ratio.scss ├── 02-generic │ ├── _focus.scss │ ├── _normalize.scss │ └── _selection.scss ├── 03-elements │ ├── _document.scss │ ├── _links.scss │ └── _typography.scss ├── 04-objects │ ├── _container.scss │ └── _content.scss ├── 05-components │ ├── _code.scss │ ├── _indenial.scss │ ├── _note.scss │ └── _section.scss ├── 06-trumps │ └── _accessibility.scss └── main.scss └── views ├── index.html └── partials ├── analytics.html ├── background.html ├── contribute.html ├── fork-me.html ├── notes.html ├── operators.html ├── practical.html ├── table-of-contents.html └── why.html /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Tim Severien 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Binary Cheatsheet 2 | 3 | This is the repository for [The Binary Cheatsheet](https://timseverien.github.io/binary-cheatsheet/), a cheatsheet of the basics of writing and manipulating binary data in modern programming languages. 4 | 5 | ## Contribution 6 | 7 | Got a suggestion? I’m happy to accept pull requests! 8 | 9 | When writing texts, please obey the following criteria: 10 | 11 | - Stick to facts 12 | - Avoid he/she (use [singular they](https://en.wikipedia.org/wiki/Singular_they) instead) 13 | - No insults 14 | - Avoid words like easy, just, etc. 15 | - Simple words are the best words 16 | - Add jokes and smart references, because I’m super dull and stuff 17 | 18 | 19 | ### Installation 20 | 21 | After cloning the repository, open the project directory in terminal, and execute `npm install`. After installation, run `npm start` to start a Browsersync session. 22 | 23 | ### Altering Content 24 | 25 | The content can be found in `src/views/partials`. Just write some good old HTML, and you’re good to go. 26 | 27 | ### Adding a Section 28 | 29 | I deliberately split up the content into sections, to make it slightly easier to maintain. If you wish to add a section, note that `src/vies/index.html` has some Mustache/Handlebars-like syntax to inline the style and include the partials. 30 | 31 | The file `bin/build/views.js` will reveal that I’ve written a poor parser to parse the views. Until I replace the parser with Handlebars, please use `{{ partialFileName }}` to add a partial. 32 | -------------------------------------------------------------------------------- /bin/build/clean.js: -------------------------------------------------------------------------------- 1 | const del = require('del'); 2 | 3 | module.exports = (gulp, config) => () => del(config.paths.clean); 4 | -------------------------------------------------------------------------------- /bin/build/images.js: -------------------------------------------------------------------------------- 1 | const imagemin = require('gulp-imagemin'); 2 | const optmizeJpg = require('imagemin-jpegtran'); 3 | 4 | const OPTIONS_IMAGEMIN = { 5 | plugins: [ 6 | optmizeJpg(), 7 | ], 8 | }; 9 | 10 | module.exports = (gulp, config) => () => { 11 | return gulp.src(config.paths.images.source) 12 | .pipe(imagemin(OPTIONS_IMAGEMIN)) 13 | .pipe(gulp.dest(config.paths.images.destination)); 14 | }; 15 | -------------------------------------------------------------------------------- /bin/build/meta.js: -------------------------------------------------------------------------------- 1 | module.exports = (gulp, config) => { 2 | return () => gulp.src(config.paths.meta.source) 3 | .pipe(gulp.dest(config.paths.meta.destination)); 4 | }; 5 | -------------------------------------------------------------------------------- /bin/build/styles.js: -------------------------------------------------------------------------------- 1 | const postcss = require('gulp-postcss'); 2 | const sass = require('gulp-sass'); 3 | const sassGlobbing = require('node-sass-globbing'); 4 | 5 | const autoprefixer = require('autoprefixer'); 6 | const cssnano = require('cssnano'); 7 | 8 | const OPTIONS_POSTCSS = [ 9 | autoprefixer(), 10 | cssnano(), 11 | ]; 12 | 13 | module.exports = (gulp, config) => () => { 14 | const OPTIONS_SASS = { 15 | importer: sassGlobbing, 16 | includePaths: [ 17 | config.paths.modules, 18 | ], 19 | }; 20 | 21 | return gulp.src(config.paths.styles.source) 22 | .pipe(sass(OPTIONS_SASS)) 23 | .pipe(postcss(OPTIONS_POSTCSS)) 24 | .pipe(gulp.dest(config.paths.styles.destination)); 25 | }; 26 | -------------------------------------------------------------------------------- /bin/build/sync.js: -------------------------------------------------------------------------------- 1 | module.exports = (gulp, config) => (done) => { 2 | config.browserSync.init({ 3 | server: { 4 | baseDir: './docs', 5 | }, 6 | }, done); 7 | }; 8 | -------------------------------------------------------------------------------- /bin/build/views.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const replace = require('gulp-replace'); 4 | 5 | const PATTERN_IMPORT_ABSOLUTE = /\{\{>\s*(.+?)\s*\}\}/gim; 6 | const PATTERN_IMPORT_RELATIVE = /\{\{\s*(.+?)\s*\}\}/gim; 7 | 8 | const getFileContents = (file) => { 9 | try { 10 | return fs.readFileSync(file); 11 | } catch (e) { 12 | return ''; 13 | } 14 | }; 15 | 16 | module.exports = (gulp, config) => { 17 | const replaceImportAbsolute = (match, partial) => { 18 | const file = path.join(config.paths.views.destination, partial); 19 | 20 | return getFileContents(file); 21 | }; 22 | 23 | const replaceImportRelative = (match, partial) => { 24 | const file = path.join(config.paths.views.partials, `${partial}.html`); 25 | 26 | return getFileContents(file); 27 | }; 28 | 29 | return gulp.series('styles', () => { 30 | return gulp.src(config.paths.views.source) 31 | .pipe(replace(PATTERN_IMPORT_ABSOLUTE, replaceImportAbsolute)) 32 | .pipe(replace(PATTERN_IMPORT_RELATIVE, replaceImportRelative)) 33 | .pipe(gulp.dest(config.paths.views.destination)); 34 | }); 35 | }; 36 | -------------------------------------------------------------------------------- /bin/build/watch.js: -------------------------------------------------------------------------------- 1 | module.exports = (gulp, config) => gulp.series('default', 'sync', () => { 2 | const reload = (done) => { 3 | config.browserSync.reload(); 4 | done(); 5 | }; 6 | 7 | gulp.watch(config.paths.images.source, gulp.series('images', reload)); 8 | gulp.watch(config.paths.meta.source, gulp.series('meta', reload)); 9 | gulp.watch(config.paths.styles.source, gulp.series('styles', 'views', reload)); 10 | gulp.watch(config.paths.views.all, gulp.series('styles', 'views', reload)); 11 | }); 12 | -------------------------------------------------------------------------------- /docs/assets/images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timseverien/binary-cheatsheet/479278d71c11bea0e455f1ac5e23de6a5785e9a4/docs/assets/images/favicon-16x16.png -------------------------------------------------------------------------------- /docs/assets/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timseverien/binary-cheatsheet/479278d71c11bea0e455f1ac5e23de6a5785e9a4/docs/assets/images/favicon-32x32.png -------------------------------------------------------------------------------- /docs/assets/images/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timseverien/binary-cheatsheet/479278d71c11bea0e455f1ac5e23de6a5785e9a4/docs/assets/images/favicon-96x96.png -------------------------------------------------------------------------------- /docs/assets/images/switch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timseverien/binary-cheatsheet/479278d71c11bea0e455f1ac5e23de6a5785e9a4/docs/assets/images/switch.jpg -------------------------------------------------------------------------------- /docs/assets/styles/main.css: -------------------------------------------------------------------------------- 1 | :focus{outline:.25em solid #e6421a} 2 | 3 | /*! normalize-scss | MIT/GPLv2 License | bit.ly/normalize-scss */html{line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}main{display:block}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}input{overflow:visible}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;display:table;max-width:100%;padding:0;color:inherit;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}details{display:block}summary{display:list-item}menu{display:block}canvas{display:inline-block}[hidden],template{display:none}::-moz-selection{background-color:#e6421a;color:#fafafa}::selection{background-color:#e6421a;color:#fafafa}body,html{color:#222;font-family:sans-serif;font-size:100%}body{background-color:#fafafa;line-height:1.6}a{color:#222;text-decoration:none;background-image:-webkit-gradient(linear,left bottom,left top,from(#222),to(#222));background-image:linear-gradient(0deg,#222,#222);background-repeat:no-repeat;background-size:100% .0625em;background-position:bottom}a:hover{color:#e6421a;background-image:-webkit-gradient(linear,left bottom,left top,from(#e6421a),to(#e6421a));background-image:linear-gradient(0deg,#e6421a,#e6421a)}a:active{color:#d03b17;background-image:-webkit-gradient(linear,left bottom,left top,from(#d03b17),to(#d03b17));background-image:linear-gradient(0deg,#d03b17,#d03b17)}small a{background-size:100% .125em}h1,h2,h3,h4,h5,h6{font-family:sans-serif;font-weight:700;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}h1{font-size:3.16049em}h2{font-size:2.37037em}h3{font-size:1.77778em}h4{font-size:1.33333em}h5{font-size:1em}h6{font-size:.75em}.container{margin:1em auto;padding-left:1em;padding-right:1em}@media (min-width:34em){.container{width:32em}}.content *{margin-top:0}.content *+:not(ul):not(li){margin-top:1em;margin-bottom:0}.code{background-color:#333;color:#fafafa;padding:2em;line-height:1.4}.code>code{display:block;white-space:pre-wrap}.code__added,.code__interest{color:#badd98}.code__removed{color:#dd9898;text-decoration:line-through}.code__comment{color:#7b7b7b}.code__comment .code__removed{color:#7b7b7b;text-decoration:line-through}.indenial{opacity:.5;text-decoration:line-through}.note{border:1px dashed #bababa;box-sizing:border-box;margin:2em 0;padding:2em}.note>:last-child{margin-bottom:0}@media (min-width:56em){.note{float:right;margin-left:1em;width:16em}}.section{overflow:hidden;margin-bottom:4em}.section--highlighted{background-color:#f3f3f3}.section--last{margin-bottom:0}.sr-only{position:absolute;height:1px;width:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only--focusable:focus{height:auto;width:auto;margin:initial;overflow:initial;clip:auto} -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | The Binary Cheatsheet 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 31 | 32 | 33 | 34 | Skip to main content 35 | 36 |
37 |
38 |

The Binary Cheatsheet

39 |

Are you a programmer who want to learn more about bits and bytes? Or do you just need to freshen up for your project? This cheatsheet is for you.

40 |
41 |
42 | 43 | 95 | 96 | 97 |
98 |
99 |

Background

100 | 101 |

Looking at your computer screen, what do you see? Text, colours, images, videos and much more. Everything you see, everything you store on your computer, every button you press is a stream of ones and zeros. Why? How does it work?

102 | 103 |

Computers parts are able to store data via tiny electronic components called flip-flops. They can be set to either of two states: “one” or “zero.” These components can store a single value we call a bit.

104 | 105 |

To store other values than ones and zeroes, a series of bits can be grouped. If one bit can have two different states, a group of two bits can have four. A group of four bits can have up to sixteen unique states. The amount of different states grows exponentially for every bit that is added to a group. s = n2, where s is the number of states, and n the number of bits within the group.

106 | 107 |

The de-facto standard is to call a group of bits a byte, and one byte contains 8 bits. The more explicit term for an 8-bit group is octet.

108 | 109 |

Binary is the purest representation of data on computers, but it isn’t easy to understand what the data represents. How do we get from binary to other values?

110 | 111 |

Representation

112 | 113 |

Many typed programming languages have datatypes like integers, floats, strings, etc. These datatypes tell the computer how to interpret binary data. Instead of modifying bits and bytes to add two integers, we can use arithmetic operators, like a plus (+), and the computer will know what to do at binary level. Dynamically typed languages do the same, but also removes the need to tell which variable has which type.

114 | 115 |

A common datatype is an unsigned integer (uint). When an integer is signed, the first bit will be used to store whether the integer is a positive or negative integer. When it’s unsigned, the data type can only store positive integers. So a uint is an integer that must be equal or greater than 0.

116 | 117 |

Let’s have look at the binary representation of such an integer, in 8 bits. A uint is a positive integer starting from 0. Incrementing is very similar to our decimal system:

118 | 119 |
    120 |
  1. Increment the least significant number
  2. 121 |
  3. If least significant number exceeds maximum value, reset and increment the number one place left
  4. 122 |
123 | 124 |
// No bits set => zero
125 | 00000000 = 0
126 | // Increment least significant bit
127 | 00000001 = 1
128 | // Least significant bit exceeds max, so we reset it and increment bit left of it
129 | 00000010 = 2
130 | 00000011 = 3
131 | 00101010 = 42
132 | 11111111 = 255
133 | 134 |

Understanding uint is quite valuable, as many programming languages use the datatype as default representation for binary data.

135 | 136 |
// JavaScript
137 | const answer = 0b00101010;
138 | console.log(answer); // 42
139 |
140 | 141 |
142 |

Why use binary?

143 | 144 |

At this point you might wonder why you’re reading this page. Why should you understand bits and bytes? How can you benefit from this knowledge when programming in higher level languages?

145 | 146 |

Imagine we’re building a web application that needs data from a webserver. The conventional communication format is JavaScript Object Notation (JSON). Let’s say we’re sending an array of 8 random integers ranging from 0 to 255:

147 | 148 |
[
149 |   10,
150 |   240,
151 |   106,
152 |   236,
153 |   244,
154 |   226,
155 |   139,
156 |   30
157 | ]
158 | 159 |

Because the data is sent as a string with a specific format, we’ll need 8 bits per character, assuming it’s UTF-8 encoded. Ignoring whitespace, above JSON string is 31 characters, making it 248 bits.

160 | 161 |

We can send the exact same data in binary, but way more efficient. Instead of returning a formatted string, because that’s what JSON is, we can send the data as one binary blob. For numbers ranging from 0 to 255, we still need 8 bits to represent each. Because each number has a fixed bit length, we can just concatinate them. The complete blob will be 64 bits long, saving just under 75% of data!

162 | 163 |
00001010 // 10
164 | 11110000 // 240
165 | 01101010 // 106
166 | 11101100 // 236
167 | 11110100 // 244
168 | 11100010 // 226
169 | 10001011 // 139
170 | 00011110 // 30
171 | 172 |

The strength of JSON isn’t size, but flexibility. Because it’s a formatted string, it’s length and contents is irrelevant. The strength of binary is it’s size. It all depends on your use-case, but a 75% reduction of bandwidth is worth considering.

173 |
174 | 175 |
176 |

Operators

177 | 178 |

Bitwise operators are operators that allow you to modify data on bit-level. Welcome to Boolean algebra.

179 | 180 |

In the following examples, we will define binary data using “binary literals.” This means they are prefixed with 0b, which is common in many programming languages. For more information, see notes.

181 | 182 |

NOT

183 |

Flipping, or negating bits can be done using the NOT (~) operator. The operator toggles all the bits.

184 |
~0b01 = 10
185 | ~0b11 = 00
186 | 187 |

AND

188 |

The AND (&) operator returns 1 for each bit only if the corresponding bits of 189 | both operands are 1’s.

190 |
0b01 & 0b11 = 01
191 | 0b01 & 0b00 = 00
192 | 193 |

OR

194 |

The OR (|) operator returns 1’s if a bit of either of the operands is 195 | 1.

196 |
0b10 | 0b01 = 11
197 | 0b00 | 0b00 = 00
198 | 0b11 | 0b10 = 11
199 | 200 |

XOR

201 |

Similar to the OR operator, the XOR (^), exclusive OR, operator only returns 1’s if 202 | either of the corresponding bits of the operands is 1, but 0 if both are.

203 |
0b10 ^ 0b01 = 11
204 | 0b00 ^ 0b00 = 00
205 | 0b11 ^ 0b10 = 01
206 | 207 |

It could be considered a shorthand of the following:

208 |
a = 0b11
209 | b = 0b10
210 | (a | b) & ~(a & b) = 01
211 | 212 |

Shift

213 |

Bit shifting is the act of shifting a set of bits to the left or the right.

214 | 215 |

To shift bits to the left, use <<. Additional bits, 0s, will be added on the right-hand side.

216 |
0b1001 << 2 = 100100
217 | 218 |

To shift bits the other way, use >>. This will discard the right-hand bits.

219 |

Note that this operation retains the first bit for signed integers. This means that negative integers stay negative.

220 | 221 |
0b1001 >> 2 = 1001
222 | 223 |

When shifting bits to the right, notice the amount of bits decreases? A zero-fill right shift (>>>) 224 | also adds bits on the left-hand side, so the amount of bits is unchanged.

225 |

Unlike a regular right shift, the zero-fill right shift also moves the sign bit in a signed integer, which is often undesired.

226 | 227 |
0b1001 >>> 2 = 001001
228 |
229 | 230 |
231 |

Practical

232 | 233 |

Read a bit at a specific position

234 |

First, a set of bits must be shifted to the right until the bit of interest is all the way on the right. To discard all other bits, 235 | we can use the AND operator with a so called bitmask.

236 |
bitmask = 0b1
237 | 
238 | // the highlighted bits are moved all the way to the right, then all other bits are cancelled out with the bitmask
239 | (0b1101 >> 2) & bitmask = 1
240 | (0b1101 >> 1) & bitmask = 0
241 | 242 |

The bitmask determines how much of the info is returned, so to get two bits, a two-bit bitmask is required.

243 | 244 |
bitmask = 0b11
245 | (0b1101) >> 2) & bitmask = 11
246 | 247 |

Set a bit

248 |

To set a specific bit to 1, you can use the OR operator. First, the bit you wish to set is shifted to the position you wish to set it to, the OR operator does the rest.

249 |
byte = 0b0000
250 | byte | (0b1 << 2) = 0100
251 | 252 |

To set a specific bit to 0, you must use the AND operator.

253 |
byte = 0b1111
254 | byte & (0b0 << 2) = 1011
255 | 256 |

If the new bit has a dynamic value, the following allows you to change a bit to any 257 | value at a given position.

258 | 259 |
x = 1 // new value of bit...
260 | n = 2 // at this location
261 | byte = 0b0010
262 | 
263 | byte ^ (-x ^ byte) & (1 << n) = 0110
264 | 265 |

Toggle a bit at a specific position

266 |

The XOR operator returns 1 if operands are unequal. By having one operand set to 267 | 1, it toggles.

268 | 269 |
n = 2 // at this location
270 | byte = 0b0100
271 | byte ^ (0b1 << n) = 0000
272 | 273 |

Store flags

274 |

Flags, a fancy name for “options,” can easily be stored in a byte. This example is inspired by the TCP protocol.

275 | 276 |
FLAG_FIN    = 0b000001
277 | FLAG_SYN    = 0b000010
278 | FLAG_RESET  = 0b000100
279 | FLAG_PUSH   = 0b001000
280 | FLAG_ACK    = 0b010000
281 | FLAG_URGENT = 0b100000
282 | 
283 | // Set header to SYN, ACK and URGENT (110010)
284 | header = FLAG_SYN | FLAG_ACK | FLAG_URGENT
285 | 
286 | // Turn off URGENT flag
287 | header = header & ~FLAG_URGENT
288 | 289 |

Hex to RGB

290 |

Colours are often stored as hexadecimals. Sometimes, you will want to get the value of each channel. Note that hexadecimals are just another representation of uints.

291 | 292 |
// mask = 11111111
293 | mask = 0xFF
294 | 
295 | // rgb = 11100110 01000010 00011001
296 | rgb = 0xE64219
297 | 
298 | // to get the red component,
299 | // shift 16 bits to the right
300 | // and get the first 8 bits
301 | // 11100110 01000010 00011001
302 | (rgb >> 16) & mask = 0xE6 // = 11100110
303 | 
304 | // to get green,
305 | // shift 8 bits to the right,
306 | // and only get the first 8 bits
307 | // 11100110 01000010 00011001
308 | (rgb >> 8) & mask = 0x42 // = 01000010
309 | 
310 | // blue is the first 8 bits
311 | // 11100110 01000010 00011001
312 | rgb & mask = 0x19
313 | 314 |

RGB to hex

315 |

You can do the opposite as well; convert RGB to hexadecimals.

316 | 317 |
r = 0xE6 // 11100110
318 | g = 0x42 // 11100110
319 | b = 0x19 // 00011001
320 | 
321 | // 11100110 01000010 00011001
322 | (r << 16) | (g << 8) | b = 0xE64219
323 |
324 | 325 |
326 |

Notes

327 | 328 |

The above code is pseudo-code, and may not work in all languages. Other than the basics—like data-types and equations—there 329 | are few things to consider in particular to make this work in your language.

330 | 331 |

Declare binary literals

332 |

Although many languages seem to support binary literals by prefixing them with 0b, some do not.

333 | 334 |
JavaScript = parseInt('0010', 2) // pre-ES6
335 | PHP        = bindec('0010')      // pre-5.4
336 | Scala      = Integer.parseInt("0010", 2)
337 | 338 |

For more information, please refer to the documentation of your preferred language.

339 | 340 |

Converting Binary to a String

341 |

Displaying binary data as a string can help debug binary values.

342 | 343 |
JavaScript = (0b1011).toString(2)
344 | PHP        = decbin(0b1011)
345 | Ruby       = "%b" % 0b1011
346 | 347 |

For more information, please refer to the documentation of your preferred language.

348 | 349 |

Bitwise operators

350 |

Some programming languages use different bitwise operators than used in this document. Please advice the documentation 351 | of your language in question.

352 |
353 | 354 |
355 |

Contribute

356 | 357 |

To ensure quality, this cheatsheet is open to contributions. If you run in to errors, have suggestions or feel you can help a hand in any way, be sure to leave an issue or pull request in the GitHub repository. Thanks!

358 |
359 | 360 |
361 | 362 | 367 | 368 | Fork me on GitHub 369 | 370 | 380 | 381 | 382 | 383 | 384 | -------------------------------------------------------------------------------- /docs/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "The Binary Cheatsheet", 3 | "short_name": "Binary Guide", 4 | "display": "standalone", 5 | "background_color": "#222", 6 | "description": "A cheatsheet for bits and bytes", 7 | "icons": [ 8 | { 9 | "src": "assets/images/favicon-16x16.png", 10 | "sizes": "16x16", 11 | "type": "image/png" 12 | }, 13 | { 14 | "src": "assets/images/favicon-32x32.png", 15 | "sizes": "32x32", 16 | "type": "image/png" 17 | }, 18 | { 19 | "src": "assets/images/favicon-96x96.png", 20 | "sizes": "96x96", 21 | "type": "image/png" 22 | } 23 | ], 24 | "related_applications": [ 25 | { 26 | "platform": "web" 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const gulp = require('gulp'); 3 | 4 | const DIR_SOURCE = path.resolve('src'); 5 | const DIR_DESTINATION = path.resolve('docs'); 6 | const DIR_TASKS = path.resolve('bin', 'build'); 7 | 8 | const config = { 9 | browserSync: require('browser-sync').create(), 10 | paths: { 11 | clean: [ 12 | DIR_DESTINATION, 13 | `!${DIR_DESTINATION}/manifest.json` 14 | ], 15 | images: { 16 | source: path.join(DIR_SOURCE, 'images', '**', '*.{gif,jpg,png,svg}'), 17 | destination: path.join(DIR_DESTINATION, 'assets', 'images'), 18 | }, 19 | meta: { 20 | source: path.join(DIR_SOURCE, 'meta', '**', '*'), 21 | destination: DIR_DESTINATION, 22 | }, 23 | modules: path.join(__dirname, 'node_modules'), 24 | styles: { 25 | source: path.join(DIR_SOURCE, 'styles', '**', '*.scss'), 26 | destination: path.join(DIR_DESTINATION, 'assets', 'styles'), 27 | }, 28 | views: { 29 | all: path.join(DIR_SOURCE, 'views', '**', '*.html'), 30 | partials: path.join(DIR_SOURCE, 'views', 'partials'), 31 | source: path.join(DIR_SOURCE, 'views', '*.html'), 32 | destination: DIR_DESTINATION, 33 | }, 34 | }, 35 | }; 36 | 37 | gulp.task('clean', require(path.join(DIR_TASKS, 'clean'))(gulp, config)); 38 | gulp.task('images', require(path.join(DIR_TASKS, 'images'))(gulp, config)); 39 | gulp.task('meta', require(path.join(DIR_TASKS, 'meta'))(gulp, config)); 40 | gulp.task('styles', require(path.join(DIR_TASKS, 'styles'))(gulp, config)); 41 | gulp.task('views', require(path.join(DIR_TASKS, 'views'))(gulp, config)); 42 | gulp.task('sync', require(path.join(DIR_TASKS, 'sync'))(gulp, config)); 43 | 44 | gulp.task('default', gulp.series('clean', 'meta', gulp.parallel('images', 'styles'), 'views')); 45 | gulp.task('watch', require(path.join(DIR_TASKS, 'watch'))(gulp, config)); 46 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bit-cheatsheet", 3 | "engines": { 4 | "node": "^12.13.0", 5 | "npm": "^6.9.0" 6 | }, 7 | "scripts": { 8 | "build": "gulp", 9 | "start": "npm run build -- watch" 10 | }, 11 | "devDependencies": { 12 | "autoprefixer": "^9.7.1", 13 | "breakpoint-sass": "^2.7.1", 14 | "browser-sync": "^2.26.7", 15 | "cssnano": "^4.1.10", 16 | "del": "^5.1.0", 17 | "gulp": "^4.0.2", 18 | "gulp-imagemin": "^6.2.0", 19 | "gulp-postcss": "^8.0.0", 20 | "gulp-replace": "^1.0.0", 21 | "gulp-sass": "^4.0.2", 22 | "imagemin-jpegtran": "^6.0.0", 23 | "node-sass-globbing": "0.0.23" 24 | }, 25 | "dependencies": { 26 | "node": "^12.13.0", 27 | "normalize-scss": "^7.0.1" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/design/favicons.ai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timseverien/binary-cheatsheet/479278d71c11bea0e455f1ac5e23de6a5785e9a4/src/design/favicons.ai -------------------------------------------------------------------------------- /src/images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timseverien/binary-cheatsheet/479278d71c11bea0e455f1ac5e23de6a5785e9a4/src/images/favicon-16x16.png -------------------------------------------------------------------------------- /src/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timseverien/binary-cheatsheet/479278d71c11bea0e455f1ac5e23de6a5785e9a4/src/images/favicon-32x32.png -------------------------------------------------------------------------------- /src/images/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timseverien/binary-cheatsheet/479278d71c11bea0e455f1ac5e23de6a5785e9a4/src/images/favicon-96x96.png -------------------------------------------------------------------------------- /src/images/switch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timseverien/binary-cheatsheet/479278d71c11bea0e455f1ac5e23de6a5785e9a4/src/images/switch.jpg -------------------------------------------------------------------------------- /src/meta/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "The Binary Cheatsheet", 3 | "short_name": "Binary Guide", 4 | "display": "standalone", 5 | "background_color": "#222", 6 | "description": "A cheatsheet for bits and bytes", 7 | "icons": [ 8 | { 9 | "src": "assets/images/favicon-16x16.png", 10 | "sizes": "16x16", 11 | "type": "image/png" 12 | }, 13 | { 14 | "src": "assets/images/favicon-32x32.png", 15 | "sizes": "32x32", 16 | "type": "image/png" 17 | }, 18 | { 19 | "src": "assets/images/favicon-96x96.png", 20 | "sizes": "96x96", 21 | "type": "image/png" 22 | } 23 | ], 24 | "related_applications": [ 25 | { 26 | "platform": "web" 27 | } 28 | ] 29 | } 30 | -------------------------------------------------------------------------------- /src/styles/00-settings/_branding.scss: -------------------------------------------------------------------------------- 1 | $branding--primary: #e6421a; 2 | $branding--secondary: #25dd22; 3 | 4 | $branding--background: #fafafa; 5 | $branding--foreground: #333; 6 | 7 | $branding--soft: #f3f3f3; 8 | -------------------------------------------------------------------------------- /src/styles/00-settings/_generic.scss: -------------------------------------------------------------------------------- 1 | $ratio-golden: 1.6180339887498948482; 2 | $ratio-perfect-forth: 1 / (3 / 4); 3 | -------------------------------------------------------------------------------- /src/styles/00-settings/_layout.scss: -------------------------------------------------------------------------------- 1 | $wrapper-spacing: 1em; 2 | $wrapper-width: 32em; 3 | -------------------------------------------------------------------------------- /src/styles/00-settings/_typography.scss: -------------------------------------------------------------------------------- 1 | $color-text: #222; 2 | -------------------------------------------------------------------------------- /src/styles/01-tools/_breakpoint.scss: -------------------------------------------------------------------------------- 1 | @import 'breakpoint-sass/stylesheets/breakpoint'; 2 | -------------------------------------------------------------------------------- /src/styles/01-tools/_golden-ratio.scss: -------------------------------------------------------------------------------- 1 | @function golden-ratio($scale, $ratio: $ratio-golden, $base: 1em) { 2 | @if $scale == 0 { 3 | @return $base; 4 | } 5 | 6 | @return $base * power($ratio, $scale); 7 | } 8 | 9 | @function power($n, $exp) { 10 | $num: 1; 11 | 12 | @if $exp >= 0 { 13 | @for $i from 1 through $exp { 14 | $num: $num * $n; 15 | } 16 | } @else { 17 | @for $i from $exp to 0 { 18 | $num: $num / $n; 19 | } 20 | } 21 | 22 | @return $num; 23 | } 24 | -------------------------------------------------------------------------------- /src/styles/02-generic/_focus.scss: -------------------------------------------------------------------------------- 1 | :focus { 2 | outline: 0.25em solid $branding--primary; 3 | } -------------------------------------------------------------------------------- /src/styles/02-generic/_normalize.scss: -------------------------------------------------------------------------------- 1 | @import 'normalize-scss/sass/normalize'; 2 | @include normalize(); 3 | -------------------------------------------------------------------------------- /src/styles/02-generic/_selection.scss: -------------------------------------------------------------------------------- 1 | ::selection { 2 | background-color: $branding--primary; 3 | color: $branding--background; 4 | } -------------------------------------------------------------------------------- /src/styles/03-elements/_document.scss: -------------------------------------------------------------------------------- 1 | html, body { 2 | color: $color-text; 3 | font-family: sans-serif; 4 | font-size: 100%; 5 | } 6 | 7 | body { 8 | background-color: $branding--background; 9 | line-height: 1.6; 10 | } 11 | -------------------------------------------------------------------------------- /src/styles/03-elements/_links.scss: -------------------------------------------------------------------------------- 1 | a { 2 | $link-color: #222; 3 | $link-color--hover: $branding--primary; 4 | $link-color--active: darken($branding--primary, 5%); 5 | 6 | color: $link-color; 7 | // font-weight: 700; 8 | text-decoration: none; 9 | 10 | background-image: linear-gradient(0deg, $link-color, $link-color); 11 | background-repeat: no-repeat; 12 | background-size: 100% (1em / 16); 13 | background-position: center bottom; 14 | 15 | &:hover { 16 | color: $link-color--hover; 17 | background-image: linear-gradient(0deg, $link-color--hover, $link-color--hover); 18 | } 19 | 20 | &:active { 21 | color: $link-color--active; 22 | background-image: linear-gradient(0deg, $link-color--active, $link-color--active); 23 | } 24 | 25 | small & { 26 | background-size: 100% (1em / 8); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/styles/03-elements/_typography.scss: -------------------------------------------------------------------------------- 1 | h1, h2, h3, h4, h5, h6 { 2 | font-family: sans-serif; 3 | font-weight: 700; 4 | line-height: 1; 5 | 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | h1 { font-size: golden-ratio(4, $ratio-perfect-forth); } 11 | h2 { font-size: golden-ratio(3, $ratio-perfect-forth); } 12 | h3 { font-size: golden-ratio(2, $ratio-perfect-forth); } 13 | h4 { font-size: golden-ratio(1, $ratio-perfect-forth); } 14 | h5 { font-size: golden-ratio(0, $ratio-perfect-forth); } 15 | h6 { font-size: golden-ratio(-1, $ratio-perfect-forth); } 16 | -------------------------------------------------------------------------------- /src/styles/04-objects/_container.scss: -------------------------------------------------------------------------------- 1 | $module: '.container'; 2 | 3 | #{$module} { 4 | margin: 1em auto; 5 | padding-left: $wrapper-spacing; 6 | padding-right: $wrapper-spacing; 7 | 8 | @include breakpoint($wrapper-width + ($wrapper-spacing * 2)) { 9 | width: $wrapper-width; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/styles/04-objects/_content.scss: -------------------------------------------------------------------------------- 1 | $module: '.content'; 2 | 3 | #{$module} { 4 | * { 5 | margin-top: 0; 6 | } 7 | 8 | * + *:not(ul):not(li) { 9 | margin-top: 1em; 10 | margin-bottom: 0; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/styles/05-components/_code.scss: -------------------------------------------------------------------------------- 1 | $module: '.code'; 2 | 3 | #{$module} { 4 | $color-code__base: saturate(darken($branding--background, 25%), 50%); 5 | $code-color__added: adjust-hue($color-code__base, 90); 6 | $code-color__removed: $color-code__base; 7 | $code-color__comment: darken($branding--background, 50%); 8 | 9 | background-color: $branding--foreground; 10 | color: $branding--background; 11 | padding: 2em; 12 | line-height: 1.4; 13 | 14 | > code { 15 | display: block; 16 | white-space: pre-wrap; 17 | } 18 | 19 | &__interest { 20 | color: $code-color__added; 21 | } 22 | 23 | &__added { 24 | color: $code-color__added; 25 | } 26 | 27 | &__removed { 28 | color: $code-color__removed; 29 | text-decoration: line-through; 30 | } 31 | 32 | &__comment { 33 | color: $code-color__comment; 34 | 35 | #{$module}__removed { 36 | color: $code-color__comment; 37 | text-decoration: line-through; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/styles/05-components/_indenial.scss: -------------------------------------------------------------------------------- 1 | $module: '.indenial'; 2 | 3 | #{$module} { 4 | opacity: 0.5; 5 | text-decoration: line-through; 6 | } 7 | -------------------------------------------------------------------------------- /src/styles/05-components/_note.scss: -------------------------------------------------------------------------------- 1 | $module: '.note'; 2 | 3 | #{$module} { 4 | $note-width: $wrapper-width * 0.5; 5 | 6 | border: 1px dashed darken($branding--background, 25%); 7 | box-sizing: border-box; 8 | margin: 2em 0; 9 | padding: 2em; 10 | 11 | > :last-child { 12 | margin-bottom: 0; 13 | } 14 | 15 | @include breakpoint($wrapper-width + $note-width + 8em) { 16 | float: right; 17 | margin-left: 1em; 18 | width: $note-width; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/styles/05-components/_section.scss: -------------------------------------------------------------------------------- 1 | .section { 2 | overflow: hidden; 3 | margin-bottom: 4em; 4 | 5 | &--highlighted { 6 | background-color: $branding--soft; 7 | } 8 | 9 | &--last { 10 | margin-bottom: 0; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/styles/06-trumps/_accessibility.scss: -------------------------------------------------------------------------------- 1 | .sr-only { 2 | position: absolute; 3 | height: 1px; 4 | width: 1px; 5 | padding: 0; 6 | margin: -1px; 7 | overflow: hidden; 8 | clip: rect(0,0,0,0); 9 | border: 0; 10 | 11 | &--focusable:focus { 12 | height: initial; 13 | width: initial; 14 | margin: initial; 15 | overflow: initial; 16 | clip: initial; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/styles/main.scss: -------------------------------------------------------------------------------- 1 | @import '00-settings/**/*.scss'; 2 | @import '01-tools/**/*.scss'; 3 | @import '02-generic/**/*.scss'; 4 | @import '03-elements/**/*.scss'; 5 | @import '04-objects/**/*.scss'; 6 | @import '05-components/**/*.scss'; 7 | @import '06-trumps/**/*.scss'; 8 | -------------------------------------------------------------------------------- /src/views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | The Binary Cheatsheet 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | Skip to main content 33 | 34 |
35 |
36 |

The Binary Cheatsheet

37 |

Are you a programmer who want to learn more about bits and bytes? Or do you just need to freshen up for your project? This cheatsheet is for you.

38 |
39 |
40 | 41 | {{ table-of-contents }} 42 | 43 |
44 | {{ background }} 45 | {{ why }} 46 | {{ operators }} 47 | {{ practical }} 48 | {{ notes }} 49 | {{ contribute }} 50 |
51 | 52 | 57 | 58 | {{ fork-me }} 59 | {{ analytics }} 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /src/views/partials/analytics.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/views/partials/background.html: -------------------------------------------------------------------------------- 1 |
2 |

Background

3 | 4 |

Looking at your computer screen, what do you see? Text, colours, images, videos and much more. Everything you see, everything you store on your computer, every button you press is a stream of ones and zeros. Why? How does it work?

5 | 6 |

Computers parts are able to store data via tiny electronic components called flip-flops. They can be set to either of two states: “one” or “zero.” These components can store a single value we call a bit.

7 | 8 |

To store other values than ones and zeroes, a series of bits can be grouped. If one bit can have two different states, a group of two bits can have four. A group of four bits can have up to sixteen unique states. The amount of different states grows exponentially for every bit that is added to a group. s = n2, where s is the number of states, and n the number of bits within the group.

9 | 10 |

The de-facto standard is to call a group of bits a byte, and one byte contains 8 bits. The more explicit term for an 8-bit group is octet.

11 | 12 |

Binary is the purest representation of data on computers, but it isn’t easy to understand what the data represents. How do we get from binary to other values?

13 | 14 |

Representation

15 | 16 |

Many typed programming languages have datatypes like integers, floats, strings, etc. These datatypes tell the computer how to interpret binary data. Instead of modifying bits and bytes to add two integers, we can use arithmetic operators, like a plus (+), and the computer will know what to do at binary level. Dynamically typed languages do the same, but also removes the need to tell which variable has which type.

17 | 18 |

A common datatype is an unsigned integer (uint). When an integer is signed, the first bit will be used to store whether the integer is a positive or negative integer. When it’s unsigned, the data type can only store positive integers. So a uint is an integer that must be equal or greater than 0.

19 | 20 |

Let’s have look at the binary representation of such an integer, in 8 bits. A uint is a positive integer starting from 0. Incrementing is very similar to our decimal system:

21 | 22 |
    23 |
  1. Increment the least significant number
  2. 24 |
  3. If least significant number exceeds maximum value, reset and increment the number one place left
  4. 25 |
26 | 27 |
// No bits set => zero
28 | 00000000 = 0
29 | // Increment least significant bit
30 | 00000001 = 1
31 | // Least significant bit exceeds max, so we reset it and increment bit left of it
32 | 00000010 = 2
33 | 00000011 = 3
34 | 00101010 = 42
35 | 11111111 = 255
36 | 37 |

Understanding uint is quite valuable, as many programming languages use the datatype as default representation for binary data.

38 | 39 |
// JavaScript
40 | const answer = 0b00101010;
41 | console.log(answer); // 42
42 |
43 | -------------------------------------------------------------------------------- /src/views/partials/contribute.html: -------------------------------------------------------------------------------- 1 |
2 |

Contribute

3 | 4 |

To ensure quality, this cheatsheet is open to contributions. If you run in to errors, have suggestions or feel you can help a hand in any way, be sure to leave an issue or pull request in the GitHub repository. Thanks!

5 |
6 | -------------------------------------------------------------------------------- /src/views/partials/fork-me.html: -------------------------------------------------------------------------------- 1 | Fork me on GitHub 2 | -------------------------------------------------------------------------------- /src/views/partials/notes.html: -------------------------------------------------------------------------------- 1 |
2 |

Notes

3 | 4 |

The above code is pseudo-code, and may not work in all languages. Other than the basics—like data-types and equations—there 5 | are few things to consider in particular to make this work in your language.

6 | 7 |

Declare binary literals

8 |

Although many languages seem to support binary literals by prefixing them with 0b, some do not.

9 | 10 |
JavaScript = parseInt('0010', 2) // pre-ES6
11 | PHP        = bindec('0010')      // pre-5.4
12 | Scala      = Integer.parseInt("0010", 2)
13 | 14 |

For more information, please refer to the documentation of your preferred language.

15 | 16 |

Converting Binary to a String

17 |

Displaying binary data as a string can help debug binary values.

18 | 19 |
JavaScript = (0b1011).toString(2)
20 | PHP        = decbin(0b1011)
21 | Ruby       = "%b" % 0b1011
22 | 23 |

For more information, please refer to the documentation of your preferred language.

24 | 25 |

Bitwise operators

26 |

Some programming languages use different bitwise operators than used in this document. Please advice the documentation 27 | of your language in question.

28 |
29 | -------------------------------------------------------------------------------- /src/views/partials/operators.html: -------------------------------------------------------------------------------- 1 |
2 |

Operators

3 | 4 |

Bitwise operators are operators that allow you to modify data on bit-level. Welcome to Boolean algebra.

5 | 6 |

In the following examples, we will define binary data using “binary literals.” This means they are prefixed with 0b, which is common in many programming languages. For more information, see notes.

7 | 8 |

NOT

9 |

Flipping, or negating bits can be done using the NOT (~) operator. The operator toggles all the bits.

10 |
~0b01 = 10
11 | ~0b11 = 00
12 | 13 |

AND

14 |

The AND (&) operator returns 1 for each bit only if the corresponding bits of 15 | both operands are 1’s.

16 |
0b01 & 0b11 = 01
17 | 0b01 & 0b00 = 00
18 | 19 |

OR

20 |

The OR (|) operator returns 1’s if a bit of either of the operands is 21 | 1.

22 |
0b10 | 0b01 = 11
23 | 0b00 | 0b00 = 00
24 | 0b11 | 0b10 = 11
25 | 26 |

XOR

27 |

Similar to the OR operator, the XOR (^), exclusive OR, operator only returns 1’s if 28 | either of the corresponding bits of the operands is 1, but 0 if both are.

29 |
0b10 ^ 0b01 = 11
30 | 0b00 ^ 0b00 = 00
31 | 0b11 ^ 0b10 = 01
32 | 33 |

It could be considered a shorthand of the following:

34 |
a = 0b11
35 | b = 0b10
36 | (a | b) & ~(a & b) = 01
37 | 38 |

Shift

39 |

Bit shifting is the act of shifting a set of bits to the left or the right.

40 | 41 |

To shift bits to the left, use <<. Additional bits, 0s, will be added on the right-hand side.

42 |
0b1001 << 2 = 100100
43 | 44 |

To shift bits the other way, use >>. This will discard the right-hand bits.

45 |

Note that this operation retains the first bit for signed integers. This means that negative integers stay negative.

46 | 47 |
0b1001 >> 2 = 1001
48 | 49 |

When shifting bits to the right, notice the amount of bits decreases? A zero-fill right shift (>>>) 50 | also adds bits on the left-hand side, so the amount of bits is unchanged.

51 |

Unlike a regular right shift, the zero-fill right shift also moves the sign bit in a signed integer, which is often undesired.

52 | 53 |
0b1001 >>> 2 = 001001
54 |
55 | -------------------------------------------------------------------------------- /src/views/partials/practical.html: -------------------------------------------------------------------------------- 1 |
2 |

Practical

3 | 4 |

Read a bit at a specific position

5 |

First, a set of bits must be shifted to the right until the bit of interest is all the way on the right. To discard all other bits, 6 | we can use the AND operator with a so called bitmask.

7 |
bitmask = 0b1
 8 | 
 9 | // the highlighted bits are moved all the way to the right, then all other bits are cancelled out with the bitmask
10 | (0b1101 >> 2) & bitmask = 1
11 | (0b1101 >> 1) & bitmask = 0
12 | 13 |

The bitmask determines how much of the info is returned, so to get two bits, a two-bit bitmask is required.

14 | 15 |
bitmask = 0b11
16 | (0b1101) >> 2) & bitmask = 11
17 | 18 |

Set a bit

19 |

To set a specific bit to 1, you can use the OR operator. First, the bit you wish to set is shifted to the position you wish to set it to, the OR operator does the rest.

20 |
byte = 0b0000
21 | byte | (0b1 << 2) = 0100
22 | 23 |

To set a specific bit to 0, you must use the AND operator.

24 |
byte = 0b1111
25 | byte & (0b0 << 2) = 1011
26 | 27 |

If the new bit has a dynamic value, the following allows you to change a bit to any 28 | value at a given position.

29 | 30 |
x = 1 // new value of bit...
31 | n = 2 // at this location
32 | byte = 0b0010
33 | 
34 | byte ^ (-x ^ byte) & (1 << n) = 0110
35 | 36 |

Toggle a bit at a specific position

37 |

The XOR operator returns 1 if operands are unequal. By having one operand set to 38 | 1, it toggles.

39 | 40 |
n = 2 // at this location
41 | byte = 0b0100
42 | byte ^ (0b1 << n) = 0000
43 | 44 |

Store flags

45 |

Flags, a fancy name for “options,” can easily be stored in a byte. This example is inspired by the TCP protocol.

46 | 47 |
FLAG_FIN    = 0b000001
48 | FLAG_SYN    = 0b000010
49 | FLAG_RESET  = 0b000100
50 | FLAG_PUSH   = 0b001000
51 | FLAG_ACK    = 0b010000
52 | FLAG_URGENT = 0b100000
53 | 
54 | // Set header to SYN, ACK and URGENT (110010)
55 | header = FLAG_SYN | FLAG_ACK | FLAG_URGENT
56 | 
57 | // Turn off URGENT flag
58 | header = header & ~FLAG_URGENT
59 | 60 |

Hex to RGB

61 |

Colours are often stored as hexadecimals. Sometimes, you will want to get the value of each channel. Note that hexadecimals are just another representation of uints.

62 | 63 |
// mask = 11111111
64 | mask = 0xFF
65 | 
66 | // rgb = 11100110 01000010 00011001
67 | rgb = 0xE64219
68 | 
69 | // to get the red component,
70 | // shift 16 bits to the right
71 | // and get the first 8 bits
72 | // 11100110 01000010 00011001
73 | (rgb >> 16) & mask = 0xE6 // = 11100110
74 | 
75 | // to get green,
76 | // shift 8 bits to the right,
77 | // and only get the first 8 bits
78 | // 11100110 01000010 00011001
79 | (rgb >> 8) & mask = 0x42 // = 01000010
80 | 
81 | // blue is the first 8 bits
82 | // 11100110 01000010 00011001
83 | rgb & mask = 0x19
84 | 85 |

RGB to hex

86 |

You can do the opposite as well; convert RGB to hexadecimals.

87 | 88 |
r = 0xE6 // 11100110
89 | g = 0x42 // 11100110
90 | b = 0x19 // 00011001
91 | 
92 | // 11100110 01000010 00011001
93 | (r << 16) | (g << 8) | b = 0xE64219
94 |
95 | -------------------------------------------------------------------------------- /src/views/partials/table-of-contents.html: -------------------------------------------------------------------------------- 1 | 53 | -------------------------------------------------------------------------------- /src/views/partials/why.html: -------------------------------------------------------------------------------- 1 |
2 |

Why use binary?

3 | 4 |

At this point you might wonder why you’re reading this page. Why should you understand bits and bytes? How can you benefit from this knowledge when programming in higher level languages?

5 | 6 |

Imagine we’re building a web application that needs data from a webserver. The conventional communication format is JavaScript Object Notation (JSON). Let’s say we’re sending an array of 8 random integers ranging from 0 to 255:

7 | 8 |
[
 9 |   10,
10 |   240,
11 |   106,
12 |   236,
13 |   244,
14 |   226,
15 |   139,
16 |   30
17 | ]
18 | 19 |

Because the data is sent as a string with a specific format, we’ll need 8 bits per character, assuming it’s UTF-8 encoded. Ignoring whitespace, above JSON string is 31 characters, making it 248 bits.

20 | 21 |

We can send the exact same data in binary, but way more efficient. Instead of returning a formatted string, because that’s what JSON is, we can send the data as one binary blob. For numbers ranging from 0 to 255, we still need 8 bits to represent each. Because each number has a fixed bit length, we can just concatinate them. The complete blob will be 64 bits long, saving just under 75% of data!

22 | 23 |
00001010 // 10
24 | 11110000 // 240
25 | 01101010 // 106
26 | 11101100 // 236
27 | 11110100 // 244
28 | 11100010 // 226
29 | 10001011 // 139
30 | 00011110 // 30
31 | 32 |

The strength of JSON isn’t size, but flexibility. Because it’s a formatted string, it’s length and contents is irrelevant. The strength of binary is it’s size. It all depends on your use-case, but a 75% reduction of bandwidth is worth considering.

33 |
34 | --------------------------------------------------------------------------------