最小的输出自身MD5值的程序

本文记录的是腾讯第二期极客比赛的赛题内容。

首先要了解一下什么是MD5算法,MD5算法简单来讲就是一个哈希映射,把一个任意长度的文件或者字符串映射到一个32位的字符串上。这个映射肯定是有损映射的,他的算法也是比较绕,具体的实现可以参考维基百科

好了,我们现在已经有了一个实现能够计算md5的算法程序了,那么题目要求是输出自身MD5的程序,简单来说就是输出可执行文件的MD5,且这个可执行文件的功能就是输出自己的MD5,另一个最优化的目标是程序的size要最小,跟一般的比赛要求速度上的性能不同,这个比赛要求程序大小最小,确实是一个比较有意思的点。正常优化程序将程序优化到最快可以采用内联函数、循环展开,尽量避免循环和冗余的条件语句。然而这个比赛可以说是“反向优化”,能用到循环的地方尽量采用循环,这样才能保证最后程序的size最小。

我的第一版程序非常简单,但是没审清题,倒也实现了功能,就是调用linux的md5sum的命令去计算自己,但是题目中不允许调用。。。因此就以失败告终。

第二个思路就很奇思妙想,那就是我构造一个字符串,程序功能就是打印这个字符串,然后字符串恰好就是自身程序的MD5,然后查阅了很多资料,感觉凉透了。参考是否存在一个字符串,它的md5值是其自身?就连找一个字符串的MD5是自己就难的一比,到现在都没找到一个,要是一个程序,经过了汇编、编译、链接等层层套之后的MD5还能维持“本心”,这个估计得借超算才行。

第三个思路就是最踏实的了,就是写一个程序其功能就是读自己,然后算一遍MD5,再打印。最后提交版本的思路也是这个思路,成绩一般般,x86赛道是504字节,arm赛道是877字节。不过也是费了一周心思的,记录一下。

  1. 优化C语言程序,尽量避免调用库函数,全局const型的要比局部变量更省空间,局部多个变量比数组更省空间,读程序利用0x400000的基址读
  2. 利用gcc翻译C语言程序为汇编程序,再汇编上动刀子,采用系统调用来写(print)和退出(exit),同时删点没用的东西
  3. 静态编译,不加入动态链接库,这样前后能差3kb
  4. sstrip工具剪裁,把生成的可执行elf文件中的无用部分剪裁掉

最后贴一下arm的代码

#inclu
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值