TernLSB
TernLSB is an esolang invented by User:None1, it uses Steganography to store its program.
How to write programs
To write a program in TernLSB, first write a program in brainfuck, then convert it into a sequence of ternary numbers using the table below. After that, add the ternary number 22 at the end of the sequence of ternary numbers which works like a string terminator.
| Ternary representation | brainfuck |
|---|---|
00
|
+
|
01
|
-
|
02
|
,
|
10
|
.
|
11
|
<
|
12
|
>
|
20
|
[
|
21
|
]
|
Then assign the last two ternary bits with the ternary representation for every channel of every pixel in the image, starting from top-left, going right then restarting at the next line from the left. If the assigned result is larger than 255, then subtract it by 9.
Note: TernLSB programs have to be stored in a lossless compressed or uncompressed image type that uses RGB or RGBA color type (e.g.: BMP and PNG image type).
How to run programs
To run a TernLSB program, get the last two ternary bits for every channel of every pixel until you get 22, starting from top-left, going right then restarting at the next line from the left. Then recover the brainfuck program using the table above. Finally, execute the brainfuck program you get.
Example Programs
Hello World
Nope. interpreter
brainfuck interpreter
Inspired by dbfi.
Cat Program
Truth Machine
Polyglot Truth Machine
The following program behaves like a Truth Machine when running in either TernLSB or StegFuck.
Infinite fibonacci sequence
Made from this brainfuck program.
XKCD Random Number
Interpreter
Currently, the esolang has a Python interpreter (which is also an encoder for writing programs in the language), written by the author of the language (User:None1), it requires the Python Imaging Library.
#Usage:
#python tlsb.py <filename> - interpret a TernLSB program
#python tlsb.py <inputfn> <brainfuckfn> <outputfn> - Encodes brainfuck into an image file to make it a TernLSB program
import sys
from PIL import Image
def bf(code):
s1=[]
s2=[]
matches={}
tape=[0]*1000000
for i,j in enumerate(code):
if j=='[':
s1.append(i)
if j==']':
m=s1.pop()
matches[m]=i
matches[i]=m
cp=0
p=0
while cp<len(code):
if code[cp]=='+':
tape[p]=(tape[p]+1)%256
if code[cp]=='-':
tape[p]=(tape[p]-1)%256
if code[cp]==',':
tape[p]=ord(sys.stdin.read(1))%256
if code[cp]=='.':
print(chr(tape[p]),end='')
if code[cp]=='<':
p-=1
if code[cp]=='>':
p+=1
if code[cp]=='[':
if not tape[p]:
cp=matches[cp]
if code[cp]==']':
if tape[p]:
cp=matches[cp]
cp+=1
def run(fn):
im=Image.open(fn)
d=im.tobytes()
fuck='+-,.<>[]'
b=''
for i in d:
try:
b+=fuck[i%9]
except:
break
bf(b)
def enc(fn,b,o):
im=Image.open(fn)
fuck='+-,.<>[]'
d=im.tobytes()
d=list(d)
w=''
for i in b:
if i in fuck:
w+=i
for i,j in enumerate(w):
d[i]=d[i]//9
d[i]=d[i]*9
d[i]+=fuck.index(j)
if d[i]>=256:
d[i]-=9
d[len(w)]=d[len(w)]//9*9+8
if d[len(w)]>=256:
d[len(w)]-=9
db=bytes(d)
Image.frombytes(im.mode,im.size,db).save(o)
if __name__=='__main__':
a=sys.argv
if len(a)==2:
run(a[1])
if len(a)==4:
enc(a[1],open(a[2]).read(),a[3])
if len(a) not in [2,4]:
print('Must pass 1 or 3 arguments')
Turing completeness
The language is of course Turing complete since brainfuck is.
See also
- StegFuck, a similar idea but uses binary bits instead of ternary ones.






