# How to perform bit and byte flipping for ASCII strings and integers

+1 vote
in Clojure

Hello all, I am learning clojure by building a fuzzer but am having some trouble finding a good solution to mutating the string inputs. For a little background the most successfull fuzzers use really basic techniques that flip bits and bytes.

I know there are bit-flip functions but they don't seem to work on strings, understandably.
So I'm thinking I convert the ascii to binary, transform, and convert back to ascii.

For example, If I'm bit flipping "test"

01110100 01100101 01110011 01110100 = "test"
11110100 01100101 01110011 01110100 ;flipping the first bit
10110100 01100101 01110011 01110100 ;flipping the two first bits

I would also like to flip entire bytes so

01110100 01100101 01110011 01110100 = "test"
10001011 01100101 01110011 01110100 ;flipping the byte

My approach is coverting a strings to binary:

(defn encode [s]
"test" -> \"01110100 01100101 01110011 01110100""
(trim (cl-format nil "~{~8,'0b ~}" (map #(int %) s))))

Looping through the string and flipping the bits somehow then converting back.

I've been struggling all day for a good approach but I wanted to see if you experts had a more elegant solution.

Also interested in doing this to ints, but not sure how to best use the (Integer/toBinaryString) function

for example

(Integer/toBinaryString 87)
=> "1010111"

But since it's a string I can't do the (bit-flip) or related library functions.

by

Great question!

So, keep in mind that Clojure strings are Java java.lang.Strings. And, so, all this documentation is relevant:

https://docs.oracle.com/javase/8/docs/api/java/lang/String.html

There are probably even better ways, but I'd start by playing with .getBytes:

The second line shows that the relationship between the contents of a given string and the underlying bytes is can be complicated (bonus points for discovering what that glyph is even though my font gave up).

The third expression shows how one might go from a integers to binary strings in case cl-format is uncomfortable.

Then from a vector of numbers we can recover a string.

As you noted, bit-flip really wants a long, though there is some hope for other types...

By the end, we've succeeded in flipping the top bit of the \H, but is the result expected?

user> (Character/getName 200)
"LATIN CAPITAL LETTER E WITH GRAVE"

I'm gonna go with, maybe.

You're adjacent to some gnarly stuff here for sure. In fact, you're in serious danger of learning all kinds of things about the number tower, Charsets, and confusing things like the fact that bytes in Java are always signed:

user> (byte-array [200])
[-56]

Hope that helps!

by
Thank you so much for your answer! It helped clear up quite a bit. I think I have a solid understanding.