magic number 详解

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/universe_hao/article/details/52779699

    magic number ,大家或多或少会在某些文章中见到过,一般对应两种情况,

一、代码中直接使用的数值

    开发人员在代码中直接用到了某个数值,这种非特定的数值一般称之为魔数,举个例子,

float radius=3.0f // 定义半径为3.0
float perimeter=radus*3.14  // 周长为半径*3.14

没有特定说明,3.14这个数就用的很魔幻,导致代码可读性差,修改不方便的问题。

正确的做法是不要在代码中直接用特定的数值,而应该将其定义为常量、枚举类型或者是宏定义(C、C++或者objective -c)。

    当然,魔术数字在程序开发中还有一个用途(这个时候它算中性词了),就是作为调试符号,便于观察和调试程序中出现的错误。
举一个常见例子,windows下的程序员在调试程序时候,如果报错,可能对如下数字(地址)比较熟悉:0xcdcd,0xcccc等。
0xcdcd 是微软的C++ Debug 运行库 为没有初始化的堆内存所做的标记,例如malloc分配出的内存,其内容可能全部都是0xcdcd。由于0xcdcd的编码,解释为中文的话为“屯”,所以windows下的程序员,windows用户应该对“屯屯屯屯屯屯”这样的字符串并不陌生。
0xcccc同样是微软的运行库为未初始化的栈空间所做的调试标记。
类似的还有 0xFDFDFD,0xFEEEFEEE,0xDEADDEAD,0xABABABAB,这些都是微软用到的幻数,在win32下程序调试的可以参考,但是不能在程序开发的代码中使用,原因很简单,这个跟平台,运行库和编译模式有很大关系,只是为了调试所设置的标记,仅此而已。
其它平台也有很多幻数,例如著名的0xDEADBEEF (dead beef)
如果自己需要编写内存管理模块,使用自己的幻数也可以很方便的做为调试所用。


二、用来标志文件的特性

    一个文件里面的内容到底是啥?单纯的Windows用户一般是看后缀。但是后缀这个东西说改就改,不可靠。所以,最保险的还是把文件类型信息写到文件里面,通常来说,也就是写到文件开头的那几个字节。这也是现在最方便,最快捷的用来辨别一个文件真实内容的方法。这个运用是特别广泛的,常见的比如

    1、Java class文件的魔数
    每一个Java Class文件都是以0x CAFEBABE开头的。我们直接打开一个class文件


    2、rar文件的Rar

    把rar文件不解压,直接用UE或者notepad++打开,头几个字节一定都是Rar开头的


    3、Zip文件的PK

    同上


    4、文本文件的BOM
    比如说,对于文本文件,开头的几个字节可以叫做BOM(Byte Order Mark),它的作用是用来标记文本文件内部是用的哪种Unicode编码,以及其字节码顺序。UTF-8,UTF-16BE,UTF-16LE等等各种Unicode编码都有自己独一无二的BOM。一般的文本编辑器也都支持 BOM。这样就不会出现乱码了。

    5、FreeBSD 上 ELF 文件的 magic number 就是文件的前四个字节依次为"7f 45 4c 46",对应的ascii字符串即 "^?ELF"。
    6、tar 文件的 magic number 是从第257个字节起为 "ustar"。
    7、PE文件中,在DOS-根之后是一个32位的签名以及魔数0x00004550 (IMAGE_NT_SIGNATURE)(意为“NT签名”,也就是PE签名;十六进制数45和50分别代表ASCII码字母P和E,它使任何PE文件都是一个有效的MS-DOS可执行文件。等等


     一般而言,硬盘数据恢复软件(如 EasyRecovery),就是靠分析磁盘上的原始数据,然后根据文件幻数来试图匹配文件格式,从而尝试识别出磁盘中那些已经从文件系统登记表中删除的文件(真实的文件内容可能没有被覆盖)。但是这种方法不是100%精确,因为磁盘中数据的随机性也很大,很多没有意义的字符串,可能被误认为是有效的幻数,从而造成回复出无效/错误的文件。(可以在EasyRecovery中自己定义文件的幻数然后让它帮你回复,不过常用的文件格式它都有记录)
    通常在应用开发中,文件读写也可能使用文件的幻数。例如读取文件时,用它来判断文件的格式是否匹配.如果不匹配则报告错误不处理文件,或者尝试读取文件的幻数标记来识别。常见的例子。例如,把一个bmp图像文件的扩展名改名为png,可能有些图像浏览/编辑软件提示:类型错误,加载失败,但是有的软件却可以识别并读出,并提示格式跟扩展名不匹配。

    所以我们可以推测命令 "file" 应该就是利用这个原理工作的。


展开阅读全文

没有更多推荐了,返回首页