Convert text to binary and back — in a browser terminal, or from the command line.
Hello ⇄ 01001000 01100101 01101100 01101100 01101111
Two independent implementations of one encoding: a browser terminal built on xterm.js, and a pair of Python CLIs that need nothing but Python 3. No build step, no packages, no framework.
Live: binaryclock.pythai.net — the converter running beside its companion BinaryClock, which reads the clock in the same 8-bit dialect. In an article: Professor Codephreak Does It Again on rage.pythai.net — both tools explained and embedded live in a WordPress post.
| Document | What's in it |
|---|---|
| README (this file) | Usage — both the terminal and the CLIs |
| TECHNICAL.md | The encoding contract, why the logic is deliberately duplicated, the terminal's completion contract, cursor and clipboard behaviour, host-page defences |
| WORDPRESS.md | Embedding in WordPress — markup, load order, jsDelivr, gotchas, troubleshooting |
Companion project: BinaryClock — a draggable 3D binary clock Web Component reading the time in this same 8-bit dialect. Decode a clock row by hand, then check yourself here.
Space-separated, 8 bits per group, most-significant bit first:
| Rule | Why |
|---|---|
| Exactly 8 bits per group | One byte, one group — the stream is self-aligning |
| One space between groups | Readable by eye, trivially splittable, copy-paste safe |
| MSB first | Matches format(n,'08b') and every reference table |
Invalid input names the offending group rather than producing mojibake:
01001000 01100101 0110a11 → ⚠️ Error: Invalid binary segment: '0110a11'
- Browser terminal — command history (↑/↓), Ctrl+L to clear,
helpwith a way back out, and a slow-blinking cursor that doesn't fight the surrounding text. - Results on their own line, with a COPY button — one click puts the conversion on the clipboard;
copydoes the same from the keyboard. - Strict validation both ways, with errors that say which group failed.
- Python CLIs — argv-driven, stdlib only, exit non-zero on misuse.
- Embeddable — the terminal drops into any page, WordPress included.
- Terminal: a browser. xterm.js loads from a CDN; nothing to install.
- CLIs: Python 3.x — no
pip install, stdlib only (sys,re).
git clone https://github.com/Professor-Codephreak/binarytotext.git
cd binarytotextThe browser terminal needs no install at all — open index.html, or embed it in
any page (WORDPRESS.md).
python3 text-to-binary.py "Hello"
# 📝 Original Text:
# Hello
#
# 🔢 Binary Output:
# 01001000 01100101 01101100 01101100 01101111
python3 binary-to-text.py "01001000 01101001"
# 🔢 Binary Input:
# 01001000 01101001
#
# 📝 Decoded Text:
# HiBoth take their input from argv, print usage and exit 1 when called with none,
and import nothing outside the standard library. Quote the argument so the shell
keeps the spaces.
Decoding rejects malformed input rather than guessing:
python3 binary-to-text.py "01001000 01100101 0110a11"
# ❌ Error: Invalid binary segment detected: '0110a11'. Please use 8-bit binary numbers.
python3 binary-to-text.py "0100100 01100101"
# ❌ Error: Invalid binary segment detected: '0100100'. Please use 8-bit binary numbers.binary_to_text() returns its error as a string instead of raising, so a backend
can call it directly and render the message without a try/except wrapper.
Open index.html and click inside the terminal. Type help for the command
list, exit to clear back to a fresh prompt.
> text2bin code is law
Binary: 01100011 01101111 01100100 01100101 00100000 01101001 01110011 00100000 01101100 01100001 01110111
> bin2text 01001000 01101001
Text: Hi
>
| Command | What it does |
|---|---|
text2bin <text> |
Encode text to 8-bit binary |
bin2text <binary> |
Decode space-separated 8-bit binary |
copy / yank |
Copy the last result to the clipboard |
help / ? |
Show the command list |
exit / quit / q / clear |
Clear the screen, fresh prompt |
| ↑ / ↓ | Command history |
| Ctrl+L | Clear |
Details worth knowing:
- The result gets a line of its own, and the prompt returns underneath it — a conversion can never print on top of the prompt, however long it takes.
- A COPY button appears at the terminal's top-right after each conversion; one click puts the result on the clipboard. Failed decodes are not copyable — the button will never hand you an error message.
- The cursor blinks slowly (a 2 s dim rather than a hard on/off), because the terminal usually sits inside reading material.
- Input is locked while a conversion runs, so keystrokes can't land in the middle of output.
> epoch
Unix epoch : 1787372528
32-bit word : 01101010 10001001 00100011 11110000
sign bit : 0 (bit 31 — the one 2038 consumes)
overflows : 2038-01-19T03:14:07Z (11y 150d away)
the bug : as32(2147483647 + 1) = -2147483648 → 1901-12-13T20:45:52Z
the fix : as64(seconds) = BigInt — 64 bits outlast the Sun
Unix time counts seconds since 1 January 1970. Held in a signed 32-bit integer, one bit pays for the sign and the remaining 31 run out at 03:14:07 UTC on 19 January 2038; the next second claims bit 31 and the value reads as 13 December 1901. Nothing crashes — the count just becomes a large negative number, and everything that trusted it starts reasoning about the past. Y2K was a base-10 shortage of digits; this is a base-2 shortage of bits, which is why a binary tool is the natural place to look at it.
The bug and the fix are each one line, in the same spirit as text2bin and
bin2text:
const as32 = (seconds) => seconds | 0; // the bug: signed 32-bit truncation
const as64 = (seconds) => BigInt(seconds); // the fix: a count that cannot run outWidening the type is the whole repair.
64-bit computing gives a signed
integer ±9.2 × 10¹⁸ seconds — about 292 billion years either side of the epoch.
Modern 64-bit kernels already store time_t that way; what remains is 32-bit
embedded systems, on-disk and on-wire formats that froze a 32-bit field, and
database columns sized in the 1990s. Migration problems, not mathematics
problems.
The companion BinaryClock
shows the same word live: its BLK panel renders the epoch as 32 bits with the
sign bit in amber and the remaining headroom counted beside it.
The same conversion functions are reachable two ways, and they are deliberately separate surfaces — neither writes into the other, so nothing changes while you are looking somewhere else:
| Terminal | Plain boxes | |
|---|---|---|
| Use it by | Typing commands | Pressing one button |
| Needs | xterm.js, a container, a keyboard that reaches it | Nothing but script.js |
| Good for | Exploring, history, epoch, help |
Phones, quick one-offs, soft keyboards |
The plain-box interface is two textareas and a flip button that alternates direction, labelled with what the next press will do:
TEXT → BINARY ↓ press → the binary box fills
BINARY → TEXT ↑ press → the text box fills
It is pure markup — the button, the fields and the error line are found by data attribute, so no inline JavaScript is needed:
<textarea data-bt-text rows="2">Hello</textarea>
<button type="button" data-bt-flip>TEXT → BINARY ↓</button>
<textarea data-bt-binary rows="3">01001000 01100101 01101100 01101100 01101111</textarea>
<div data-bt-message></div>
<script src="https://cdn.jsdelivr.net/gh/Professor-Codephreak/binarytotext@main/script.js"></script>Either surface works on its own. embed.html is a ready-to-paste
block containing both — drop it into a WordPress Custom HTML block or any web
page; see WORDPRESS.md.
Five minutes, this tool only.
-
In the terminal, type
text2bin A. You get01000001. Read it right to left (1, 2, 4, 8, 16, 32, 64, 128): that is 65. -
Type
text2bin a. You get01100001— 97. -
Put the two side by side. Exactly one bit differs, in the 32s column:
A 01000001 a 01100001 ^ this bit, worth 32 -
Type
bin2text 01001000 01101001and read what comes back. -
Now build a byte by hand — pick positions that add to 66 — and decode it. Check yourself: you should get
B.
Concept. Characters are numbers. A byte holds a number from 0 to 255; a
character set is an agreement about which number stands for which symbol, and
ASCII is the agreement almost everything inherited. Case is not a property of a
letter in that scheme — it is a single bit, the 32s column, which is why A and
a sit exactly 32 apart and why the difference between shouting and not is one
lamp on a panel. The bits carry no opinion about this. 01000001 is 65, and it
is A, and it is a shade of dark red, and it is a machine instruction, depending
entirely on what is agreed to be reading it. Meaning lives in the interpretation,
not in the bits.
.
├── index.html # Browser UI shell (loads xterm.js, hosts #xterm-container)
├── script.js # Terminal: commands, conversion, clipboard, cursor
├── style.css # Page chrome for the standalone demo
├── text-to-binary.py # CLI: text → binary
├── binary-to-text.py # CLI: binary → text
├── README.md # This file
├── TECHNICAL.md # How and why it is built this way
└── WORDPRESS.md # Embedding guideThe browser and Python implementations are independent — neither imports the other, and neither is built from the other. That is deliberate: the conversion is a handful of lines, and duplicating it keeps both halves dependency-free. TECHNICAL.md explains the trade in full, including the character-set caveat above U+00FF.
from importlib import import_module
b2t = import_module('binary-to-text')
b2t.binary_to_text("01001000 01101001") # 'Hi'textToBinary("Hi"); // '01001000 01101001'
binaryToText("01001000 01101001"); // 'Hi'Both pure, both terminal-independent.
Both converters run live inside a WordPress post on rage.pythai.net, published by mindX's AuthorAgent: Professor Codephreak Does It Again: a Binary Clock and a Text ↔ Binary Converter for the Curious Beginner (post 1408).
The post loads script.js unmodified from this repository through the jsDelivr CDN, alongside xterm.js. This is the exact markup running on that page — paste it into any WordPress post/page whose author has unfiltered_html (or a Custom HTML block):
<div id="xterm-container" style="width:100%;height:480px;overflow:hidden;"></div>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/css/xterm.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/xterm.js"></script>
<script src="https://cdn.jsdelivr.net/gh/Professor-Codephreak/binarytotext@main/script.js"></script>Essentials:
- Order is fixed: container → xterm.js →
script.js. The script runs on load and needs both the globalTerminalandid="xterm-container"to exist already. A missing container is the usual cause of "the converter disappeared". - Give the container a height, or it collapses to nothing.
style.cssis not needed — wrap the container in your own bordered<div>for the green terminal frame.- Soft keyboards may not drive
term.onKey; the reference post adds a plain single-field fallback using the same 8-bit rule — one textarea, two buttons (text → binary,binary → text), converting in place so the input is the output.
WORDPRESS.md has the full guide — unfiltered_html and KSES, wpautop, embedding the BinaryClock widgets alongside this terminal, pinning a commit so a push can't change your published page, verification snippets, and a troubleshooting table.
Companion: BinaryClock — the same 8-bit dialect as a live 3D clock, embedded in the same post.
binary-to-text © Gregory L. Magnusson — CC0 1.0 Universal. Free to modify and distribute.
🔧 Built for developers · 💡 designed for simplicity · 🔒 powered by logic