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.