这纯粹是出于学术上的好奇,但我经常在 Windows (Win10Pro64) 和 Android 上发现没有被混淆的文件,但在每个实际相关字符之间包含一堆NUL字符,因此很难按原样阅读在 Windows 上(至少在 Android 上,我使用的资源管理器应用程序 - X-plore - 在编辑模式下作为文本启动时似乎会自动删除)。这是一个例子:
这纯粹是出于学术上的好奇,但我经常在 Windows (Win10Pro64) 和 Android 上发现没有被混淆的文件,但在每个实际相关字符之间包含一堆NUL字符,因此很难按原样阅读在 Windows 上(至少在 Android 上,我使用的资源管理器应用程序 - X-plore - 在编辑模式下作为文本启动时似乎会自动删除)。这是一个例子:
这是一个包含可打印 ASCII 字符集之外的字符的二进制文件。
因为这些字符是“不可打印的”,Notepad++ 将它们显示为描述性块。您可能会看到其他人,如下所示。在这里,您可以看到从二进制 0 /
0x00
到 255 /的所有值0xFF
(这是可以存储在单个字节中的最大值)。第 1、2 和 3 行显示的值通常称为“控制字符”,用于影响终端、光标位置等... a
NUL
的值为 0 /0x00
。BS
控制字符是“ Backspace ”,指示应用程序删除一个字符并将光标向后移动一格。值得注意的是和之间的“缺失”或不可见字符......这里是“水平制表符”和“换行”字符 - 前者是相当不言自明的,后者将使文本流动到下一个线。BS
VT
在第 4 行和第 5 行,您可以看到整个可打印的 ASCII 字符集。空格 (
) 的二进制值是 32 /
0x20
,感叹号的值是 33 /0x21
,等等......第 5 行末尾的有趣方框是DEL
控制字符 - 127 /0x7F
。包括 128 及以上的所有值要么是“扩展 ASCII ”,要么也是不可打印的,并且这些值从第 6 行开始显示为它们的原始值 - 例如:
x80
. 没有很好的方法来确定如何解释这些 - 一些 DOS 应用程序使用其中一些字符在终端上的“窗口”、框或区域周围生成框架。有关更多信息,请参阅 wiki 页面的“字符组”部分。
在“十六进制编辑器”中查看与上述相同的文件,您通常会在 ASCII 表示旁边看到原始二进制值。
当文件包含纯文本以外的数据时(例如:它是一个应用程序或其他二进制文件),您会看到很多非打印字符,因为它们从未用于人类消费......在此类文件中,数据以二进制形式排列,通常遵循严格的结构或格式。在某些情况下,数据表示大量数字(通过将多个字节连接在一起),在其他情况下,它们可能表示“机器代码”或直接呈现给处理器的原始指令。
您可能能够在此类二进制文件中看到字符串,但这更多是“偶然”而不是故意 - 应用程序本身必须知道当您看到消息时要在屏幕上打印什么,这就是这样。
字符串在二进制文件中编码的常见方法有两种。
1.C字符串
此格式使用 8 位字符,并以
NUL
字符结束字符串。该字符串在文件中立即可见,如下所示 - 请注意终止的NUL
.2. UTF-16
此格式使用 16 位字符(即:连接的两个字节),并且可以表示Unicode描述的代码点的一部分。在这里,如果您在字符之间阅读,您会看到字符串有些可见
NUL
......这种格式在面向 Windows 的应用程序中非常常见。你能看到
Logical Disks
第二行的字符串吗?二进制文件还可以在其中存储其他资源——例如图像、声音、XML、JSON、档案等……如果需要,应用程序可以在运行时将资源提取到磁盘,或者通常可以直接从内存中处理它们。
通常可以使用工具以自动化方式提取这些资源,但在某些情况下,该文件不是按照开放/通用标准设计的,因此需要一些手动干预。
当你创建一个文件来存储数据时,你可以存储一系列字节。1 个字节是 0 到 255 之间的任意数字。在许多文件格式中,使用 0 到 255 之间的任意数字来存储数据就足够了。
但是随着系统变得越来越复杂和先进,开发人员有时需要存储远大于 255 的数字。2 字节 = 256*256 = 65535,4 字节 = 256*256*256*256 = 4294967296。所以通过组合 4 个字节,可以存储从 0 到 4294967295 的值。
您甚至可以将 8 个或更多字节组合成一个数字,这通常发生在需要 64 位(8x8 字节)的 64 位应用程序中。
因为存储的数字通常很低,所以大部分字节都是 0,也就是 NUL。所以在一个文件中,你会看到很多 NUL,因为它们都是 64 位结构中的低值。
为什么不优化文件?因为大多数程序员使用为他们存储数据的函数,并且他们牢记每一个场景,包括存储大数字。
NUL
这是一种非常流行的存储字符串的约定:通常程序会知道字符串开头的位置,并且会因为找到(或NULL
或\0
)字符而知道字符串已经结束。如果将其与 CSV 进行比较,您可以将其视为分隔每列的逗号。除了这里它是一个特殊字符,不能输入也不能打印,除了分隔字符串结尾没有其他用途。
您可能认为这很脆弱,并且确实会导致无数安全问题。但是直到今天,许多字符串仍然以这种方式分隔。
但是,在您的屏幕截图中,这可能具有不同的含义,具体到您正在使用的应用程序。总的来说,二进制数据不是用文本编辑器读取的:)