1.1 文件头



描述了文件的整体信息,常见的字段有魔数、检验码、版本号、文件大小等。

顾名思义,即是将文件的整体信息通常放在文件的开头。

在少数情况下,也会将文件头放在文件的尾部,也就是‘文件尾’,但是一般还是叫做 文件头

1 魔数


魔数作为文件格式的标识,一般用于识别文件是否程序所能处理的文件。其值可以随意选取,主要看设计者自身的喜好。

例如 zip 格式的魔数就是 “PK\x03\x04”,其中 PK 就是设计者 Philip Katz 的名字首字母。

一般程序在分析文件时,会先判断魔数的值是否匹配,不匹配就表明文件格式不正确。

需要注意的是,假如魔数正确,文件格式并非一定能够读取正确,还需要进一步判断。

2 检验码


文件头通常还会有个检验码,用于检验文件是否完整并且没有经过修改的。这个检验码可以使用 crc, 可以使用 md5,也可以使用其它算法。

这也是检查文件格式的正确性中的重要一步,因为即便是魔数相同,校验码所采用的算法不同,和校验码所作的位置不同,所计算的校验码,基本上是不一的,所以进一步就,能区分出文件格式是否正确。

3 版本号


文件头通常还会包含版本号。

版本号不同,就表明文件格式发生变化,可能变化很小,也可能变化很大;可能是某些字段的值在解释上发生变化,也可能是直接添加了一些结构。所以导致文件的读取方式可能会有所不同。

版本号有时只是单独一个数字,不断往上递增。有时也会拆分成两个数字,为主版本号和次版本号。主版本号修改,通常表示文件格式发生大变动。而次版本号修改,通常只是表示添加了一些小功能。

4 字节顺序


字节顺序在文件格式设计中至关重要。

字节顺序分为大端字节序和小端字节序。不同的机器字节序有可能不同,设计文件格式时需要考虑文件用什么字节序保存数据的。

读取和存储的字节序不一致就会导致程序出错。

5 通用结构


通用结构定义如下:

struct FileHeader{
    uint8 mMagic[4];    //魔数
    uint8 mHash[16];    //检验码
    uint32 mEndian;     //字节序
    uint32 mVersion;    //文件版本
    ...
};