Bottom is a lightweight encoding format used by Discord and Tumblr users from all around the world. This document aims to detail the Bottom specification officially, so that implementing it correctly is as easy as possible.
Each character in Bottom holds a purpose of some sort. These are detailed here for your convenience, and will be referred to in depth below.
Unicode escape(s) | Character | Value |
---|---|---|
U+1FAC2 |
π« | Integer 200 |
U+1F496 |
π | Integer 50 |
U+2728 |
β¨ | Integer 10 |
U+1F97A |
π₯Ί | Integer 5 |
U+002C |
, | Integer 1 |
U+2764 , U+FE0F |
β€οΈ | Integer 0 |
Unicode escape(s) | Character | Purpose |
---|---|---|
U+1F449 , U+1F448 |
ππ | Byte terminator |
πβ¨β¨β¨πππππ₯Ί,,,ππππ,πππβ¨β¨β¨β¨π₯Ί,,ππππβ¨π₯Ίππππ,πππβ¨,,,ππ
ππ,,,,
, as according to the character table above, is
50 + 50 + 1 + 1 + 1 + 1
, or 104. This sequence would thus represent U+0068
or h
,
which has a decimal value of 104
.bottom -> values (BYTE_TERMINATOR values)* BYTE_TERMINATOR
values -> value_character+ | null_value
value_character -> π« | π | β¨ | π₯Ί | ,
null_value -> β€οΈ
BYTE_TERMINATOR -> ππ
Note that EBNF fails to capture any notion of semantic validity, i.e character ordering. It's technically possible to encode character ordering rules into the grammar, but that is not shown here for the sake of brevity and simplicity.
ππ,,,,ππππ
or ππππ,,,,ππ
. As such, ππ
alone is illegal.ππ,,,,
alone is illegal, but ππ,,,,ππ
is valid.ππ,,,,ππβ€οΈππππ,,,,ππ
and ππ,,,,ππβ€οΈππ
are valid, but ππ,,,,ππβ€οΈ
alone is illegal.For each byte b
of the input stream:
v
be the decimal value of b
.o
be a buffer of Unicode scalar values.v
is zero, encode this byte as β€οΈ (U+2764
, U+FE0F
)v
is non-zero, repeat the below until v
is zero:
v >= character_value
is satisfied. Let this be character_value
.character_value
to o
.character_value
from v
.o
.An implementation can thus be expressed as the following pseudo-code:
let o = new string
for b in input_stream:
let v = b as number
if v is 0:
o.append("β€οΈ")
else:
loop:
if v >= 200:
o.append("π«")
v = v - 200
else if v >= 50:
o.append("π")
v = v - 50
else if v >= 10:
o.append("β¨")
v = v - 10
else if v >= 5:
o.append("π₯Ί")
v = v - 5
else if v >= 1:
o.append(",")
v = v - 1
else:
break
o.append("ππ")
return o