Go back

Bits, bytes and pieces

Mar 18, 2026 · 10 min read

In this article

  • A bit of digging
  • Bits, bytes, and binary
  • Counting in binary
  • Combinations in bits
  • Powers of two and storage
  • Bytes and characters — ASCII
  • Back to CIDs

I set out to understand the UnixFS specification but before I do so, I have to figure out the anatomy of a CID and the Mutable File System. Only then shall i be able to make sense of this spec.

This is a decision i took just so i can go in-depth, hopefully.

Why am i going down this path? Well, it is because i recently learned a CID is 256 bits in size, ~32 bytes, and for a moment i was confused how 256 bits became 32 bytes. Apparently, a byte is exactly 8 bits. I need to understand all of this from first principles.

A bit of digging

There's an electrical engineering backstory to why computers ended up using binary instead of a decimal numbering system. It comes down to logarithms and information theory — Claude Shannon showed that binary was the most efficient way to represent information in electronic circuits. Two stable voltage states (high/low) are far easier to distinguish reliably than ten, which is what you'd need for decimal.

Early machines like the EDVAC (Electronic Discrete Variable Automatic Computer) went with 44-bit words. These computers were mostly built by engineers, mathematicians, and computer scientists to do hardcore numeric calculations — scientific computing, ballistics tables, that sort of thing.

Then came commercial computing, and the company that was quite instrumental in leading this paradigm shift was IBM.

IBM introduced a different way of thinking about things. While the folks working with machines like EDVAC were concerned with 5 or 6-bit words optimized for numbers, IBM introduced the concept of 8-bit characters. They standardized the byte as an 8-bit entity.

Here's where the win-win came in for both the mathematicians and the engineers: IBM proposed arranging hardware to treat groups of 4 bytes as a 32-bit word. This meant IBM could dominate commercial computing (where character processing mattered) while also boasting competitive speed in scientific computing (where 32-bit arithmetic mattered). Two birds, one stone.

Bits, bytes, and binary

Computers use the binary number system.

  • Decimal numbers: what we're already used to — 0, 1, 2, 3, ... 9 (base 10)
  • Binary numbers: 0, 1 (base 2)

Why binary? When you look at computer memory, you discover that it actually consists of a whole bunch of individual electronic switches. Each switch can be in one of two states — on or off, 1 or 0. That's a bit.

The main grouping for bits is 8 bits, referred to as a byte. The byte is the primary unit of computer storage. All computer data is ultimately stored as bits and bytes. There are different storage mediums, and in each case, the medium needs to be set up to store bits (0s and 1s):

  • An SSD, which is the most common drive in our computers today, stores data using electronic switches (flash memory cells that trap or release electrical charge)
  • A hard disk — when you open it up, you'll discover individual sections on spinning platters that are magnetically polarized. Depending on the polarity direction, a section is considered a 0 or a 1
  • CDs, DVDs, Blu-Ray — these use tiny pits and lands on a reflective surface, read by a laser. A transition between pit and land represents a 1, no transition represents a 0

Counting in binary

Let's start with what we already know — counting in decimal.

0 + 1 = 1
1 + 1 = 2
2 + 1 = 3
...
8 + 1 = 9
9 + 1 = ??

In the decimal system, there are only 10 digits (0 through 9). There's no 11th digit, so when we hit 9 + 1, what do we do? We "carry".

What does carrying actually mean? When a digit in a column reaches its maximum value and you add 1 more, that column resets to 0 and the next column to the left gets bumped up by 1. That bump is the "carry".

So 9 + 1: the ones column maxes out at 9, resets to 0, and we carry 1 to the tens column. We get 10. Then 10 + 1 = 11, 11 + 1 = 12, and so on.

What happens at 19 + 1? Same thing — the 9 in the ones column resets to 0, we carry 1 to the tens column (1 becomes 2), and we get 20.

Now, counting in binary...

0 + 1 = 1
1 + 1 = ??

We only have two digits in binary (0 and 1). When we add 1 + 1, there's no third digit, so we carry the 1 over. It becomes 10.

1 + 1 = 10. How does that even make sense?!

It works the exact same way as decimal. In decimal, when you run out of digits at 9, you carry. In binary, you run out of digits at 1. That's it. Same principle, smaller set of digits.

1 + 1 = 10
10 + 1 = 11
11 + 1 = 100
100 + 1 = 101
101 + 1 = 110
110 + 1 = 111
111 + 1 = 1000

So 1, 10, 11, 100, 101, 110, 111, 1000 are the first 8 numbers of the binary number system.

Here are the first 16 numbers with their decimal equivalents:

Decimal    Binary
───────    ──────
  0        0
  1        1
  2        10
  3        11
  4        100
  5        101
  6        110
  7        111
  8        1000
  9        1001
  10       1010
  11       1011
  12       1100
  13       1101
  14       1110
  15       1111

So for example, 6 in decimal = 110 in binary. How do we verify that? Each position in binary represents a power of 2, reading right to left: 2⁰ = 1, 2¹ = 2, 2² = 4. So 110 = (1 × 4) + (1 × 2) + (0 × 1) = 6.

Think of it like decimal place values, but with powers of 2 instead of powers of 10. In decimal, you have the ones place, tens place, hundreds place. In binary, you have the ones place (2⁰ = 1), twos place (2¹ = 2), fours place (2² = 4), eights place (2³ = 8), and so on. Each position doubles the value of the one before it.

Combinations in bits

How many different combinations of values can we store in a given number of bits?

With 1 bit, we get 2 combinations: 0 and 1. That's pretty much useless on its own because the only reasonable representation is true or false — where 1 is true and 0 is false. In real life, data is more than just booleans.

With 2 bits, we get 4 combinations: 00, 01, 10, 11.

With 3 bits, we get 8 combinations: 000, 001, 010, 011, 100, 101, 110, 111.

With 4 bits, we get 16 combinations.

The formula: n bits = 2ⁿ combinations.

Bits    Combinations
────    ────────────
 1= 2
 2= 4
 3= 8
 4      2= 16
 5      2= 32
 6      2= 64
 7      2= 128
 8      2= 256
 9      2= 512
 10     2¹⁰ = 1024

And these individual bits can represent any data type — numbers, provinces, states, locations, characters, whatever you need.

An analogy might help here. Say we want to store location data. Canada has 13 provinces and territories. We can store all of them in 4 bits because 4 bits gives us up to 16 combinations (0000 through 1111) — 13 fits comfortably.

But we can't do that for the states in Nigeria. Nigeria has 36 states (plus the FCT), and that's well above 16 combinations. We simply do not have enough space in 4 bits to store all the states in 9ja!

6 bits would conveniently hold that data for us, since we get up to 64 combinations with 6 bits.

When we're designing a program, we need to decide how many bits to allocate for what quantities.

Powers of two and storage

Those numbers — 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 — are familiar especially if you're buying computers. You'll notice that memory and storage capacities come in powers of two: 8GB, 16GB, 32GB, 64GB, etc. That's because that's what the computer understands at the hardware level.

Scaling it up:

Unit                Power of 2    Bytes
────                ──────────    ─────
1 Kilobyte (KB)     2¹⁰           1,024
1 Megabyte (MB)     2²⁰           1,048,576
1 Gigabyte (GB)     2³⁰           1,073,741,824
1 Terabyte (TB)     2⁴⁰           1,099,511,627,776

Notice how 1 kilobyte is a little over 1,000 (it's 1,024), and the same pattern holds for the rest. This is because these units use powers of 2 internally, even though we casually round them to powers of 10 in everyday language.

There's actually some disagreement between electrical engineers and computer scientists on whether we should be using powers of two or powers of ten for these units. This is why the IEC introduced binary prefixes in 1998 — a "bi" infix to intentionally distinguish them:

  • Kilobyte (KB) vs Kibibyte (KiB)
  • Megabyte (MB) vs Mebibyte (MiB)
  • Gigabyte (GB) vs Gibibyte (GiB)
  • Petabyte (PB) vs Pebibyte (PiB)

This distinction is quite evident in distributed systems and ecosystems like IPFS, where binary prefixes like PiB (pebibytes) are used. I remember seeing this PiB unit for the first time while working on a small change in the filecoin-pin repo.

Bytes and characters — ASCII

So we know a byte is 8 bits, which gives us 256 possible values (0 through 255). How do we use those 256 patterns to represent text?

ASCII is an encoding that represents each typed character as a number. Each number fits in one byte, so the range is 0 to 255.

Some key mappings:

  • A is 65, B is 66, ... Z is 90
  • a is 97, b is 98, ... z is 122
  • 0 (the character) is 48, 1 is 49, ... 9 is 57
  • Space is 32

So when you type "Hi", your computer is actually storing the bytes 72 105 — that's H (72) and i (105). 100 typed characters takes up 100 bytes. Text is quite compact compared to images and video.

ASCII works great for English, but it only defines 128 characters. Remember the formula — n bits = 2ⁿ combinations. ASCII uses 7 bits, so 2⁷ = 128 possible patterns. A byte has 8 bits (2⁸ = 256 patterns), but ASCII only needed the first 128.

Adding that 8th bit doubles the total combinations from 128 to 256, but ASCII simply didn't assign characters to those extra patterns. For languages like Mandarin, Arabic, or Greek, we need something bigger.

That's where Unicode comes in — an encoding system that can represent virtually every character in every language. UTF-8, the most common Unicode encoding, uses 1 to 4 bytes per character, and it's backwards-compatible with ASCII.

Back to CIDs

And this is where it comes full circle. A CID (Content Identifier) in IPFS is 256 bits. Now i know that a byte is 8 bits, so 256 ÷ 8 = 32 bytes. That's 32 bytes to uniquely identify any piece of content on a distributed network. With 256 bits, we get 2²⁵⁶ possible combinations — a number so astronomically large that the probability of two different pieces of content producing the same CID is effectively zero.

Not bad for a bunch of 0s and 1s, huh.