Binary Digits picoCTF 2026 Solution

Published: March 20, 2026

Description

This file doesn't look like much... just a bunch of 1s and 0s. But maybe it's not just random noise. Can you recover anything meaningful from this?

Download the file and inspect its contents.

The file contains ASCII '1' and '0' characters - interpret them as binary data.

bash
head -c 100 digits.bin

Solution

Want to try it yourself first?

The guided walkthrough reveals hints one step at a time.

Walk me through it
  1. Step 1
    Inspect how the digits are framed
    Observation
    I noticed the file size was 3096 bytes and the description said it contained 1s and 0s, which suggested I needed to determine whether separators like spaces or newlines existed between the bit characters before I could correctly slice them into 8-bit groups.
    Look at the first ~200 bytes with od -c. You need to know whether '0' and '1' are space-separated, newline-separated, or contiguous before you slice into 8-bit groups.
    bash
    head -c 200 digits.bin | od -c
    bash
    wc -c digits.bin

    Expected output

    0000000   0  1  1  0  0  1  0  0  0  1  1  0  0  1  0  1  0  1  1  0  0
    0000025   0  0  0  0  1  1  0  0  1  0  1  0  1  1  0  0  1  0  1  0  0
    ...
           3096 digits.bin
    What didn't work first

    Tried: Run 'xxd digits.bin' or 'hexdump digits.bin' to inspect the file instead of od -c.

    xxd and hexdump show you the raw hex values of each byte, which confirms the file holds 0x30 (ASCII '0') and 0x31 (ASCII '1') bytes, but the columnar layout obscures whether separators like spaces or newlines exist between bits. od -c is more direct because it prints the character representation of each byte and makes whitespace separators immediately visible as entries in the dump.

    Tried: Skip the inspection step and assume 8-bit grouping with no separators based on the file size.

    If the file has newlines after every 8 bits (a common layout), wc -c counts those newline bytes too, so dividing by 8 gives a wrong byte count and the slice logic misaligns. The od -c inspection reveals any separator bytes so you can strip them before slicing.

    Learn more

    od -c prints each byte as a printable character (or escape), so you immediately see whether the file is one long run of 0/1, or whether there are spaces, tabs, or newlines between groups. wc -c divided by the bit-grouping (usually 8) tells you how many bytes the decoded flag should be, which catches off-by-one mistakes early.

  2. Step 2
    Inspect the file
    Observation
    I noticed the challenge described the file as containing 1s and 0s, which suggested the data was ASCII-encoded binary rather than raw bytes, so reading the raw content would confirm the encoding scheme before attempting any decoding.
    Open digits.bin and confirm it contains a sequence of '1' and '0' ASCII characters representing binary data.
    bash
    cat digits.bin
    What didn't work first

    Tried: Run 'file digits.bin' or 'xxd digits.bin | head' to determine the file type before reading it.

    The 'file' command reads magic bytes and reports the type as 'ASCII text', which is correct but tells you nothing about the encoding scheme. xxd shows 0x30/0x31 bytes but the hex listing looks like noise without context. Reading the raw content with cat immediately reveals the visual pattern of 1s and 0s, making the binary ASCII encoding obvious.

    Tried: Try to open digits.bin in an image viewer or treat it as a raw binary file after seeing it is 3096 bytes.

    digits.bin contains ASCII text characters, not raw binary pixel data, so image viewers and binary parsers will fail or show garbage. The file must first be decoded - each group of 8 ASCII characters converted to one byte - before the result can be saved as a JPEG and opened as an image.

    Learn more

    The distinction between binary data and ASCII text representing binary is fundamental. The file here contains the literal characters '0' (ASCII 48) and '1' (ASCII 49) - not actual binary values 0 and 1. The file is valid text that you read with your eyes and then interpret mathematically.

    This encoding is common in low-level education and CTF introductory challenges because it makes binary arithmetic visible. Every 8 characters form one byte (octet), and each character position represents a power of two from 27 (128) down to 20 (1). For example, 01100101 = 0+64+32+0+0+4+0+1 = 101 = ASCII 'e'.

    In real-world applications, binary-to-text representations are used whenever binary data must traverse a text-only channel: Base64 is the most common (used in email MIME, JSON web tokens, and PEM certificates), while raw binary-as-ASCII is mostly pedagogical or used in signal-level protocols like old-school modems.

  3. Step 3
    Decode binary in CyberChef or Python
    Observation
    I noticed that digits.bin is confirmed to hold ASCII '0' and '1' characters with no separators, which suggested grouping them into 8-character chunks and converting each with int(chunk, 2) to reconstruct the original bytes; the resulting JPEG magic bytes would then confirm the output is an image containing the flag.
    The fastest path is CyberChef: paste the binary string, add a "From Binary" operation, and the decoded data appears. The file decodes to a JPEG image. Save the output as a .jpg and open it to see the flag hidden in the image. See CTF encodings for the broader toolkit.
    python
    python3 -c "
    data = open('digits.bin').read().strip().replace('\n','').replace(' ','')
    img = bytes(int(data[i:i+8],2) for i in range(0,len(data),8))
    open('decoded.jpg','wb').write(img)
    print('Saved decoded.jpg - open it to see the flag')
    "
    What didn't work first

    Tried: Use CyberChef 'From Hex' or 'From Base64' instead of 'From Binary' because the file extension is .bin.

    The .bin extension refers to the content being binary data conceptually, not that the file uses hex or base64 encoding. The actual file bytes are ASCII '0' and '1' characters, so only the 'From Binary' operation in CyberChef interprets them correctly. 'From Hex' expects pairs of hex digits (0-9, a-f) and 'From Base64' expects the base64 alphabet; both will produce garbled output or an error on a string of only 0s and 1s.

    Tried: Decode directly with 'int(data, 2)' on the entire string and then call chr() on the result, expecting a flag string.

    Converting the entire binary string as a single integer produces one very large number, not a sequence of bytes. The correct approach is to slice the string into 8-character chunks and convert each chunk independently with int(chunk, 2), building a bytes object. Here the decoded result is a JPEG image, not a text string, so chr() would also fail - the output must be written as raw bytes and then opened as an image file.

    Learn more

    Python's int(bits, 2) converts a binary string to an integer using base 2. Slicing with data[i:i+8] steps through the string in 8-character windows, one byte at a time. Building a bytes object first lets you call .rstrip(b'\x00') to strip trailing null padding before decoding - many encoders zero-pad to a block boundary, and a stray \x00 in the decoded string trips up downstream tooling.

    The same logic applies to other bases: int(s, 8) for octal, int(s, 16) for hexadecimal. bytes.fromhex() and base64.b64decode() handle the most common CTF encodings.

    A useful mental shortcut: printable ASCII (32-126) fits in 7 bits, so the MSB is always 0 for those characters. If the flag is all printable ASCII you can sanity-check by confirming every 8th bit is 0, but always slice the full 8 bits when decoding so you don't mangle non-ASCII bytes.

Interactive tools
  • Base64 & Base32 DecoderDecode Base64 and Base32 strings with auto-detection. Multi-layer mode unwraps nested encodings automatically.
  • Recipe ChainStack decoders into a pipeline: Base64, hex, ROT, XOR, Morse, URL, Atbash, Vigenère, and more. Magic mode auto-discovers the chain. Bookmark the URL to save it.
  • Number Base ConverterConvert numbers between binary, octal, decimal, and hexadecimal instantly. Enter any value and see all four bases update in real time.
Alternate Solution

Use the Binary → Hex Converter on this site to convert the binary data to hex, then interpret each hex byte as ASCII. You can also paste chunks of the binary into the Number Base Converter to convert individual 8-bit groups to their decimal/ASCII equivalents.

Flag

Reveal flag

picoCTF{h1dd3n_1n_th3_b1n4ry_...}

The binary string decodes to a JPEG image. Use CyberChef 'From Binary' to decode, save as .jpg, and open the image - the flag text is printed on it.

Key takeaway

Encoding schemes represent binary data as printable text characters using a numeric base, and recognizing the encoding is the entire skill. Binary (base 2), octal (base 8), decimal (base 10), hexadecimal (base 16), and base64 are all lossless transforms that differ only in how densely they pack bits into characters. Each group of 8 binary digits maps to exactly one byte, so the conversion is purely arithmetic and reversible with a single Python expression or a CyberChef operation.

Related reading

Want more picoCTF 2026 writeups?

Useful tools for Forensics

What to try next