0xCAFEBABE与Hexspeak

如果将Java源码编译后的class文件以16进制方式打开,会发现前4个字节都是0xCAFEBABE
0xcafebabe.jpg

References:

Snipaste_2021-01-12_16-12-21.png

文件必须以一些魔术数字(或字符串)开头,使其易于识别为有效的文件。例如zip(PKZip)固定以0x504b0304开头,这样程序读取开头的4个字节就知道这个文件的类型能不能解析了,毕竟后缀名这种东西可有可无的没啥用。(很多CTF题会以zip文件做文章,感兴趣可以找一找)
ex-local-header.png

那为什么class文件会选择这个字符呢?Java编程语言之父,詹姆斯•高斯林(James Gosling),曾这样说过:

在Java中使用CAFEBABE作为魔数(magic number)的过程, 说起来有些曲折:

我和小伙伴们经常去一个叫St Michael’s Alley的地方吃午餐。根据当地传说, 在黑暗的过去, Grateful Dead(感恩至死乐队)在出名前曾在此地表演。这绝对是一个因Grateful Dead Kinda Place而闻名的地方(总感觉这句翻译的怪怪的)。Jerry(乐队成员)去世时, 他们甚至建了一座佛教风格的小神龛。在我们过去常去那里的时候,把这个地方叫做Cafe Dead

可以看到,这是一个十六进制数. 那时候我正好维护一些文件的编码格式,需要用到两个魔数(magic numbers): 一个用于对象持久化文件, 另一个用于类文件. 于是我就用CAFEDEAD作为对象持久化文件的魔数, 查找了一些适合放在CAFE(似乎是一个不错的主题)后面的4位16进制的字符,最终我敲下BABE并决定就是它了。

当时, 这个魔数并没有什么特别的意义, 也看不出来有什么重要的, 或许很快就会消失在历史中。所以CAFEBABE成为class文件的魔数,CAFEDEAD成为持久对象的魔数. 但没多久持久化对象(persistent object)技术真的消失了, 就如同魔数CAFEDEAD的含义一样 -- 最终被RMI技术代替了。

0xCAFEBABE的十进制数是3405691582,把每一位加起来得到的是43,恰好大于42——生命、宇宙以及任何事情的终极答案(出自道格拉斯·亚当斯所作的小说《银河系漫游指南》)。另外,43也是个质数,You see, magic everywhere. Even in the last sentence.

根据wiki的记载

Hexspeak最早是程序员用来清晰独特地标记内存和数据的一些魔术数字,使用以0-9与A-F构成的16进制数表示一些简单的英文单词。Hexspeak的转写规则为:数字“0”表示字母“O”,“1”表示“I”或“L”,“5”表示“S”,“7”表示“T”,“6”、“9”则各自表示“G”与“g”,其它的数字则可利用画谜和Leet的规则来借代字母,例如“defecate”就可用“DEFECA7E”或“DEFEC8”来表示。Hexspeak(16进制魔术数字)是一种类似Leet的英文单词转写形式。

而Leet的词条中:

Leet(英文中亦称 leetspeak 或 eleet。Leet拼写法:L337, 3L337, 31337或1337),又称黑客语,是指一种发源于西方国家的BBS、在线游戏和黑客社区所使用的文字书写方式。通常是把拉丁字母转变成数字或是特殊符号,例如E写成3、A写成@等。或是将单字写成同音的字母或数字,如to写成2、for写成4等等。

到这忽然想起LeetCode了,然后又想起了论坛里也经常发一些反和谐的字,比如河蟹(和谐)、反云力(反动)等等,果然大家都是如此的相似啊,哈哈。

标签: none

添加新评论

ali-01.gifali-58.gifali-09.gifali-23.gifali-04.gifali-46.gifali-57.gifali-22.gifali-38.gifali-13.gifali-10.gifali-34.gifali-06.gifali-37.gifali-42.gifali-35.gifali-12.gifali-30.gifali-16.gifali-54.gifali-55.gifali-59.gif

加载中……