编译器产生的输出文件的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
BuildOutput620.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值:
BuildOutput630.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值:
BuildOutput640.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值:
BuildOutput650.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
BuildOutput2.exe 17BFC8E72EEC200E5E792673C56BB236
两个MD5值不同,应该与Delphi6类似。
似乎事情有些线索了,输出为可执行文件时,相同代码两次产生的MD5值会不同。但学需要进一步验证。下次有时间之后继续。
PS:个人新干博客地址 http://www.lontoken.com/