2024 Clojure状态调查!中分享您的想法。

欢迎!有关如何工作的更多信息,请参见关于页面。

+1
Clojure

大家好,我通过构建fuzzer学习Clojure,但有些麻烦找不到对字符串输入进行变异的好解决方案。作为背景,最成功的fuzzer使用非常基础的技巧,比如反转位和字节。

我知道有位反转函数,但它们似乎不适用于字符串,这是可以理解的。
因此,我正在考虑将ASCII转换为二进制,进行转换,然后转换回ASCII。

例如,如果我要反转“test”的位

01110100 01100101 01110011 01110100 = "test"
11110100 01100101 01110011 01110100 ;反转第一个位
10110100 01100101 01110011 01110100 ;反转前两个位

我还想反转整个字节

01110100 01100101 01110011 01110100 = "test"
10001011 01100101 01110011 01110100 ;反转字节

我的方法是将字符串转换为二进制

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

遍历字符串,并 somehow反转位,然后转换回。

我已经为此抗争了一整天,但我想看看是否有更多的优雅解决方案。

同时也想为整数做这件事,但不确定如何最好地使用 (Integer/toBinaryString) 函数

例如

(Integer/toBinaryString 87)
=> "1010111"

但是它是一个字符串,所以我不能做 (bit-flip) 或相关库函数。

非常感谢!

1 答案

+2
by

这是一个很好的问题!

请注意,Clojure 字符串实际上是 Java 的 java.lang.Strings。因此,所有这些文档都是相关的。

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

可能还有更好的方法,但我会先尝试使用 .getBytes

第二行显示了给定字符串的内容与底层字节之间的关系可能会很复杂(如果你发现那个符号,可以加分)。

第三行展示了如何从整数到二进制字符串转换,以防 cl-format 令你感到不适。

然后,我们可以从一个数字向量中恢复一个字符串。

正如你所指出的,bit-flip 真实地需要一个 long,尽管对其他类型还有一线希望...

最终,我们成功地翻转了 \H 的最高位,但是结果是预期的那样吗?

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

我觉得,也许是

你肯定会被一些复杂的东西困扰。实际上,你面临着一座高楼,了解了各种关于数字塔、字符集和令人困惑的事物,比如 Java 中的字节总是带符号的。

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

希望这能帮到你!

by
非常感谢你的回答!这澄清了很多东西。我认为我已有了一个扎实的理解。
...