Hackthebox – Brainy – part 1

When opening the brainy.txt file, a large string of only 6 specific characters appeared which made no sense to me. (the example below is actually for hello world)

++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.

However, selecting a little part of the code and putting it into Google already revealed that it was written in the esoteric ‘brainfuck’ language.

Using a brainfuck visualizer to analyze what the algorithm actually does helped me understand which steps need to be taken in code. The essence is very simple, as the code consists of only the character +, , >, < , ., [ and ].

  • + Increase the current memory value with 1 unless the value is 255, then continue at 0
  • Decrease the current memory value with 1 unless the value i 0, then continue at 255
  • > Move the position in memory one field to the right
  • < Move the position in memory one field to the left
  • [ Starting position of a loop
  • ] Ending position of a loop, if the current memory value equals 0, break out of the loop and continue, else move back to the corresponding [
  • . Print the current memory value
#!/usr/bin/env python3
import re

#Function to check if the syntax is pure brainf*ck syntax containing only values '+-<>.,[]'
def bfValidate(bf):
    bfallow = '[+-<>.,\[\]]+$'
    if not (re.match(bfallow, bf)):
        print("BF-Syntax Error")
        exit()

#Function to create a new dictionary list with values for processing
def bfDecode(dictInput):
    #define variables
    bfdict = {} # dictionary for containing all brainf*ck values
    loopdict = {} # dictionary for loop positions
    datadict= [0 for i in range(300)] # list for containing the data values
    stack = []
    plaintext=""

    #set memory position to starting point
    mempos=0
    bfpos=0
    #Create dictionaries
    for i, c in enumerate(dictInput):
        bfdict.update([(i,c)])
        if c == '[':
            stack.append(i)
        elif c == ']':
            if len(stack) == 0:
                raise IndexError("No matching closing bracket for %i" % i)
            loopdict[stack.pop()] = i

    if len(stack) > 0:
        raise IndexError("No matching opening bracket for %i" % i)

        
    while bfpos character is encountered
        # Increment value if a + character is encountered
        # Make sure that the value does not exceed 255
        if(bfdict[bfpos]=='+'):   
            if(datadict[mempos]==255):
                datadict[mempos]=0
            else:
                datadict[mempos]+=1
        # Decrease value if a - character is encountered
        # Make sure that the value does not go below 0
        elif(bfdict[bfpos]=='-'):
            if(datadict[mempos]==0):
                datadict[mempos]=255
            else:
                datadict[mempos]-=1
        elif(bfdict[bfpos]=='>'):
            mempos+=1
        # Move to the previous memory position if a < character is encountered
        elif(bfdict[bfpos]=='<'):
            mempos-=1
        # Print the corresponding ascii value if a . character is encountered
        elif(bfdict[bfpos]=='.'): 
            plaintext = plaintext + str(chr(datadict[mempos]))
        # Find the corresponding [ position from the loopdict if a ] character is 
        # encountered and move the bfpos position back to that point if the current
        # memory value is not equal to 0
        elif(bfdict[bfpos]==']' and not (datadict[mempos]==0)):
            bfpos=list(loopdict.keys())[list(loopdict.values()).index(bfpos)]
        bfpos+=1
    print(plaintext)

#Request a file which contains the bf-code
bfinput=""
filename=input("Please provide a filename: ")
try:
    file=open(filename,'r')
except:
    print("File",filename,"not found")
    quit()

for line in file:
    bfinput = bfinput+line

bfValidate(bfinput)
bfDecode(bfinput)

When running this code with the input as provided in the brainy.txt, a long string with values is provided which at that point did not make any sense (just like the brainfuck code).

Solution to first part of Brainy challenge hackthebox

To be continued in part 2