编译器产生的输出文件的MD5值与生成代码的关系

编译器产生的输出文件的MD5值与生成代码的关系

背景

因发布给用户的产品需要升级,每次升级使用的是版本号加”增量更新“的方法,自动更新服务器保存当前版本号与所有文件的MD5值,用户本地保存本地的版本号。登录时,若用户本地的版本号与服务器上的版本号不一致,则根据嗠器上文件的MD5与本地所有文件计算的MD5值比较,若不同,则更新。但现在在Delphi6中,程序的代码没有作更新,前后再次产生的文件的MD5却不同。Delphi6将生成文件的当前时间戳添加到了输出文件中。从二进制进的角度来看,代码相同的程序,只是编译的时间不一样,产生的文件却是不同的。Delphi6的这种画蛇添足的做法,实在叫人费解。

既然Delphi6这么做,难道这是“业内行规”,为了弄明白,那就只有一一探个明白了。

Delphi6输出文件MD5

已经知道了,代码不一样编译时间不同,其输出文件的MD5也不同,但若是在输出文件中,将编译时间戳的影响去除了,是其它因素对它的影响是怎样的呢。

程序如下: 
program BuildOutput_6;

{$APPTYPE CONSOLE}  

uses  
  SysUtils;  

var  
  aNum: Integer;  

begin
  Writeln('==Delphi 6的输出文件==');  

  aNum := 0;

  Writeln(IntToStr(aNum)); 

  Writeln('按回车键退出。');
  readln;
end.

在不修改代码的情况下,编译两次产生的文件:BuildOutput61.exe、BuildOutput62.exe,另外将时间戳强制改为2008-08-08 08:08:08之后分别产生的文件为:BuildOutput610.exe和BuildOutput620.exe; 
4个文件的MD5值: 
BuildOutput61.exe 7C4574F2C7614273076D78BC06C5824F 
BuildOutput62.exe 5BF6B4BF7DE37A71BC4060F95C544FC5 
BuildOutput620.exe 68B6114E66DC2912656810278C616A94 
BuildOutput
620.exe 68B6114E66DC2912656810278C616A94

将代码做略微调整: 
program BuildOutput_6;

{$APPTYPE CONSOLE} 

uses
  SysUtils; 

var
  aNum: Integer;

begin
  Writeln('==Delphi 6的输出文件==');

  aNum := 1;

  Writeln(IntToStr(aNum));

  Writeln('按回车键退出。');
  readln;
end.

此次产生的BuildOutput630.exe的MD5值: 
BuildOutput
630.exe 4B44FC3E49A35081004D1D7BCE4BDAB4 
BuildOutput63_0.exe的MD5与前面2对应文件的MD5值不同,代码的改动,已经影响的最后的输出文件。

将代码的语句顺序调整: program BuildOutput_6;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  aNum: Integer;

begin
  aNum := 0;

  Writeln('==Delphi 6的输出文件==');

  Writeln(IntToStr(aNum));

  Writeln('按回车键退出。');
  readln;
end.

此次产生的BuildOutput640.exe的MD5值: 
BuildOutput
640.exe DB2DA5F6F3AE5B3F71330DB17A116A98 
BuildOutput64_0.exe的MD5与前面2对应文件的MD5值不同,代码的改动,已经影响的最后的输出文件。

将代码的空白行去除: 
program BuildOutput_6;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  aNum: Integer;

begin
  Writeln('==Delphi 6的输出文件==');
  aNum := 0;

  Writeln(IntToStr(aNum));

  Writeln('按回车键退出。');
  readln;
end.

此次产生的BuildOutput650.exe的MD5值: 
BuildOutput
650.exe 68B6114E66DC2912656810278C616A94 
BuildOutput65_0.exe的MD5与前面2对应文件的MD5值一样同。

JAVA输出文件MD5

JAVA代码如下: public class BuildOutput_6 {

     public static void main(String[] args){
         System.out.println("==Java 6的输出文件==");

         int i = 0;

         System.out.println("i = " + i);

     }
 }

两次编译产生的.class文件的MD5如下: BuildOutput61.class 5F50C342B17C8DBFE22E3E71311CB358 
BuildOutput62.class 5F50C342B17C8DBFE22E3E71311CB358 
两个MD5值相同。

VC9.0输出文件MD5

代码如下: public class BuildOutput_6 {

     public static void main(String[] args){
         System.out.println("==Java 6的输出文件==");

         int i = 0;

         System.out.println("i = " + i);

     }
 }

两次编译产生的.exe文件的MD5如下: BuildOutput1.exe EB77754D7216FD4AC3FF62EB7A0E3A2B 
BuildOutput
2.exe 17BFC8E72EEC200E5E792673C56BB236 
两个MD5值不同,应该与Delphi6类似。

似乎事情有些线索了,输出为可执行文件时,相同代码两次产生的MD5值会不同。但学需要进一步验证。下次有时间之后继续。

PS:个人新干博客地址 http://www.lontoken.com/

posted @ 2013-04-02 18:31  lontoken  阅读(834)  评论(0编辑  收藏  举报