为啥在windows XP与windows 7下使用同一MD5效验工具,计算出同一文件的MD5值不一致?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥在windows XP与windows 7下使用同一MD5效验工具,计算出同一文件的MD5值不一致?相关的知识,希望对你有一定的参考价值。

    复制粘贴只是我们字面上看起来不变,但是计算机将文字进行储存需要进行编码,而编码方式的不同将导致储存文件的方式(字节内容)不同,所储存的文件为两个不同的两个文件,进而导致md5计算有差别。

    最简单的例子比如:用windows自带的记事本(notepad.exe)储存同样一个小写的a,先采用默认的编码方式(ANSI)保存(也就是直接保存)为a_a。保存完后另存为a_u,编码方式选择Unicode。对a_a.txt和a_u.txt进行md5校验值比对,你将会发现两者结果是不一样的。

    另外一个例子,如果你用记事本和MS winword保存相同文字内容,计算的MD5校验值也是不同的,因为word文件内除了保存我们看得见的内容外还要保存其他文档格式或文档信息等。

    注:文件名不同对文件内容不产生影响,也就对MD5校验值不产生影响。同样内容的两个文件,即使文件名不同也会产生相同的md5校验值。自己验证,详细请参考文件系统和操作系统相关知识!

参考技术A md5算法对“相同的数据”生成(几乎)唯一的散列值。

winxp,和win7下对同一文件,如果内容一致,会得到同一值。
如果得到的值不同,说明文件内容不同,即使有1个空格,一个字节,1个bit的不同,
都会导致散列值完全不一样。

直接鼠标右击文件,查看属性->文件效验,如果值不同说明文件内容变化。追问

属性里没有文件校验

追答

我的Ghost WinXp都有这个文件效验功能,怎么能说没有。


也可以用windiff工具检验文件是否变动。

懂编程的,可以用php,python,perl,java等预置的md5函数精确计算一下具体值。

通常是文件有变化导致值不同。


值不同,肯定是文件数据不同。文件数据不同的成因可能多样,

1、比如染毒,染恶意软件,会给文件增加内容

2、内存老化失效,网络传输-读写错个别bit。对于老化或松动内存,剪贴也会出错,解压缩会经常CRC效验错。

参考技术B TXT内容确定没有改过?多加空格也算追问

完全的复制粘贴

追答

这就不知道了 不太熟悉md5 刚才去百度看了下 貌似没有关于这类的问题 lz的观察力还是挺强的

为啥 SetTimeZoneInformation 在 Windows XP 中不起作用?

【中文标题】为啥 SetTimeZoneInformation 在 Windows XP 中不起作用?【英文标题】:Why SetTimeZoneInformation does not work in windows XP?为什么 SetTimeZoneInformation 在 Windows XP 中不起作用? 【发布时间】:2012-07-29 04:29:39 【问题描述】:

我有一个 delphi 程序,可以将窗口的时区信息设置为特定的开始和结束日期。它在 Windows 7、vista 和 Server 2008 中完美运行。但在 XP 和 Server 2003 等早期 Windows 版本中却不行。我很好奇我的代码有错误还是 XP 问题?

这是我的代码:

program SetTimeZoneInfo;

$APPTYPE CONSOLE

uses
  SysUtils,
  Messages,
  windows;

const
  SE_TIME_ZONE_NAME = 'SeTimeZonePrivilege';
  SE_SYSTEMTIME_NAME = 'SeSystemtimePrivilege';

function NTSetPrivilege(sPrivilege: string; bEnabled: Boolean): Boolean;
var
  hToken: THandle;
  TokenPriv: TOKEN_PRIVILEGES;
  PrevTokenPriv: TOKEN_PRIVILEGES;
  ReturnLength: Cardinal;
begin
  Result := True;
  if not (Win32Platform = VER_PLATFORM_WIN32_NT) then Exit;

  // obtain the processes token
  if OpenProcessToken(GetCurrentProcess(),
    TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
  begin
    try
      // Get the locally unique identifier (LUID) .
      if LookupPrivilegeValue(nil, PChar(sPrivilege),
        TokenPriv.Privileges[0].Luid) then
      begin
        TokenPriv.PrivilegeCount := 1; // one privilege to set

        case bEnabled of
          True: TokenPriv.Privileges[0].Attributes  := SE_PRIVILEGE_ENABLED;
          False: TokenPriv.Privileges[0].Attributes := 0;
        end;

        ReturnLength := 0; // replaces a var parameter
        PrevTokenPriv := TokenPriv;

        // enable or disable the privilege

        AdjustTokenPrivileges(hToken, False, TokenPriv, SizeOf(PrevTokenPriv),
          PrevTokenPriv, ReturnLength);
      end;
    finally
      CloseHandle(hToken);
    end;
  end;
  // test the return value of AdjustTokenPrivileges.
  Result := GetLastError = ERROR_SUCCESS;
  if not Result then
    raise Exception.Create(SysErrorMessage(GetLastError));
end;

var
  tzi: TTimeZoneInformation;
  lpwdResult, LHResult: Cardinal;
begin
  if Win32MajorVersion >= 6 then
  begin
    Writeln('NTSetPrivilege SE_TIME_ZONE_NAME enabled ? ' + BoolToStr(NTSetPrivilege(SE_TIME_ZONE_NAME, True), True));
  end;
  Writeln('NTSetPrivilege SE_TIME_ZONE_NAME enabled ? ' + BoolToStr(NTSetPrivilege(SE_SYSTEMTIME_NAME, True), True));

  tzi.Bias:= -210;

  tzi.DaylightDate.wYear:= 2012;
  tzi.DaylightDate.wMonth:= 3;
  tzi.DaylightDate.wDay:= 20;
  tzi.DaylightDate.wHour:= 23;
  tzi.DaylightDate.wMinute:= 59;
  tzi.DaylightDate.wSecond:= 59;
  tzi.DaylightBias:= -60;

  tzi.StandardDate.wYear:= 2012;
  tzi.StandardDate.wMonth:= 9;
  tzi.StandardDate.wDay:= 20;
  tzi.DaylightDate.wHour:= 23;
  tzi.DaylightDate.wMinute:= 59;
  tzi.DaylightDate.wSecond:= 59;
  tzi.StandardBias:= 0;

  if not SetTimeZoneInformation(tzi) then
      Writeln('SetTimeZoneInformation Error Message: '+ SysErrorMessage(GetLastError))
  else
    Writeln('SetTimeZoneInformation : Success');

  LHResult:= SendMessageTimeout(
                      HWND_BROADCAST,   // reciever window handle
                      WM_SETTINGCHANGE, // message
                      0,                // WParam
                      0,                // LParam
                      SMTO_NORMAL,      // return if reciever hange
                      5,                // timeout in seconds
                      lpwdResult        // result
                      );
  if LHResult = 0 then
    Writeln('SendMessageTimeout Error Message: '+ SysErrorMessage(GetLastError))
  else
    Writeln('SendMessageTimeout : Success');

  if Win32MajorVersion >= 6 then
    Writeln('NTSetPrivilege SE_TIME_ZONE_NAME disabled ? ' + BoolToStr(NTSetPrivilege(SE_TIME_ZONE_NAME, False), True));
  Writeln('NTSetPrivilege SE_TIME_ZONE_NAME disabled ? ' + BoolToStr(NTSetPrivilege(SE_SYSTEMTIME_NAME, False), True));
  Readln;
end.

【问题讨论】:

描述它是如何失败的。 “它不起作用”没有帮助。 另外,您的错误检查完全不正确。您必须在调用每个 API 函数后立即调用 GetLastError。在NTSetPrivilege 中,您有 3 次调用 API 函数,但只有一次调用 GetLastError。更何况你没有检查AdjustTokenPrivileges的返回值,所以你不知道它是否失败。 读下代码你有一行写着if Win32MajorVersion >= 6 then。这意味着您只尝试获取 Vista 及更高版本的 SE_TIME_ZONE_NAME priv。你为什么这样做? 我们需要的不止这些。哪个 API 调用失败。与该故障相关的错误代码是什么。您正在运行代码,我们没有。您可以在代码中突出显示 API 调用失败的精确点。我们不能。 大卫,“它不起作用”意味着它不设置时区信息、偏差、DST 开始和 DST 结束日期 【参考方案1】:

Windows 为新版本时,使用:SetDynamicTimeZoneInformation。 如果它是旧的(例如:XP),请像以前一样使用 SetTimeZoneInformation。 告诉我它是否解决了问题。我也必须做类似的事情。 谢谢。 罗德里戈·皮门塔·卡瓦略

【讨论】:

以上是关于为啥在windows XP与windows 7下使用同一MD5效验工具,计算出同一文件的MD5值不一致?的主要内容,如果未能解决你的问题,请参考以下文章

Windows 7 与 Windows XP 上 Firefox 中的字体行间距

Windows XP 与 Vista/7 上的 MS Crypto API 行为

VB.net 中的 IP 地址查找(XP 与 Windows 7)

为啥 SetTimeZoneInformation 在 Windows XP 中不起作用?

哪里是存储与XP,Vista和Windows 7兼容的日志文件的安全位置?

无需单独安装或更新即可与 Windows xp、7、8 一起使用的最佳 .net 框架版本