# Framework for Writing Flexible Bruteforcers

When writing a bruteforcer, it’s easiest to think of it as mapping some kind of output to a monotonically-increasing number.

Like for one of the solved PlaidCTF question, the answer string was composed from the eight letters “plaidctf”, which conveniently is a power of 2, meaning each output character can be represented with 3 bits. To write a bruteforcer for a string composed of these characters, you might imagine generating a 3-bit number (i.e. from 0 to 7) then mapping it to the character set for one output character, or a 30-bit number if the output string was 10 characters. Unsurprisingly, this was exactly what I did for my solver script. The output string was generated from a BitVector of `171 * 3` bits.

But what if the output was composed of several different pieces that cannot be represented uniformly as a set of bits?

One solution might be to emulate such a behaviour using an array of integers, like how I modified my solver script in version 2 to handle a character set of arbitrary length.

In this post, I will walk-through writing a basic, but flexible, bruteforcer with accompanying code snippets in Go.

# Keeping State

Continuing on the CTF puzzle, the BitVector was replaced with an array of `Int`s. Each `Int` will represent one character of the output string. We can thus represent the state like so (for simplicity, let’s limit the output string to 2 characters):

```type state struct {
digit int
}
```

In order to increment each digit, we can write a function that increments `state.digit` until a certain number, then resets it to zero.

To make it generic, we will write a function that returns another function that manipulates a digit position, so we don’t have to copy & paste the code for each digit position:

```// returns a function that manipulates the digit at given pos
func digitManipulator(pos int) func(*state) bool {
return func(s *state) bool {
s.digit[pos]++
if s.digit[pos] == MAX_NUMBER {
s.digit[pos] = 0
return true
}
return false
}
}
```

We will talk more about the boolean return value later.