解码嵌入在二进制文件中的日期/时间十六进制值

D P*_* P. 3 c# decoding

我正在尝试编写类似于本网站上的C#程序:http://www.digital-detective.co.uk/freetools/decode.asp

您能告诉我如何将以下公告中列出的十六进制数转换为日期/时间值.

  • Windows 64位(小端)十六进制值FF03D2315FE1C701应转换为=Sat, 18 August 2007 06:15:37 UTC
  • Windows 64位OLE十六进制值FBE8DF975D3FE340应转换为= Sun, 02 December 2007 22:11:42 UTC
  • Unix 32位(大端)十六进制值46C3B400应转换为= Thu, 16 August 2007 02:18:40 UTC
  • Apple Mac绝对十六进制值219216022应转换为=Thu, 13 December 2007 05:20:22 UTC
  • HFS 32位(小端)十六进制值CD4E55C3应转换为= Mon, 05 November 2007 22:50:53 Local

我试图使用以下代码来做到这一点,但它不会返回正确的结果:

double decValue = int.Parse("A2C3B446", System.Globalization.NumberStyles.HexNumber);
System.DateTime dtDateTime = new DateTime(2013, 1, 1, 0, 0, 0, 0);
dtDateTime = dtDateTime.AddSeconds(decValue).ToLocalTime();
Console.WriteLine("Decimal Value: " + decValue);
Console.WriteLine(dtDateTime);
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 17

您首先需要一个实用程序方法,它从流中读取字节并处理字节序.这可能看起来像:

    public static byte[] ReadBytes(Stream s, int size, bool littleEndian) {
        var bytes = new byte[size];
        var len = s.Read(bytes, 0, size);
        if (len != size) throw new InvalidOperationException("Unexpected end of file");
        if (BitConverter.IsLittleEndian != littleEndian) Array.Reverse(bytes);
        return bytes;
    }
Run Code Online (Sandbox Code Playgroud)

Windows日期很简单,直接由DateTime.FromFileTimeUtc()支持:

    public static DateTime ConvertWindowsDate(byte[] bytes) {
        if (bytes.Length != 8) throw new ArgumentException();
        return DateTime.FromFileTimeUtc(BitConverter.ToInt64(bytes, 0));
    }
Run Code Online (Sandbox Code Playgroud)

用你的价值测试它:

    var date1 = DateReaders.ConvertWindowsDate(DateReaders.ReadBytes(
                    new MemoryStream(new byte[]{0xFF,0x03,0xD2,0x31,0x5F,0xE1,0xC7,0x01}), 8, true));
Run Code Online (Sandbox Code Playgroud)

按预期产生{8/18/2007 6:15:37 AM}.


OLE日期很简单,直接由DateTime.FromOADate()支持:

    public static DateTime ConvertOLEDate(byte[] bytes) {
        if (bytes.Length != 8) throw new ArgumentException();
        return DateTime.FromOADate(BitConverter.ToDouble(bytes, 0));
    }
Run Code Online (Sandbox Code Playgroud)

用你的价值测试它:

    var date2 = DateReaders.ConvertOLEDate(DateReaders.ReadBytes(
                    new MemoryStream(new byte[] {0xFB,0xE8,0xDF,0x97,0x5D,0x3F,0xE3,0x40 }), 8, true));
Run Code Online (Sandbox Code Playgroud)

产生{12/2/2007 10:11:41 PM}


Unix日期值是从1970年1月1日,UTC时间凌晨0:00开始的毫秒数:

    public static DateTime ConvertUnixDate(byte[] bytes) {
        if (bytes.Length != 4) throw new ArgumentException();
        return new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(
                  BitConverter.ToUInt32(bytes, 0));
    }
Run Code Online (Sandbox Code Playgroud)

用你的价值测试它:

    var date3 = DateReaders.ConvertUnixDate(DateReaders.ReadBytes(
                   new MemoryStream(new byte[] {0x46,0xC3,0xB4,0x00}), 4, false));
Run Code Online (Sandbox Code Playgroud)

产生{8/16/2007 2:18:40 AM}


Apple Mac绝对时间记录为依赖于CPU,需要在生成它的机器上进行转换.显示的值"219216022"是古怪的,它似乎是十进制而不是十六进制,就像所有其他的一样.我将跟随Baldrick的领导:

public static DateTime ConvertAppleDate(byte[] bytes) {
    if (bytes.Length != 4) throw new ArgumentException();
    return new DateTime(2001, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(
              BitConverter.ToUInt32(bytes, 0));
}
Run Code Online (Sandbox Code Playgroud)

HFS日期是自1904年1月1日0:00 AM以来的秒数.请注意,HFS日期是本地时间,但HFS Plus日期是UTC.我将假设本地,因为这是您记录的结果:

    public static DateTime ConvertHFSDate(byte[] bytes) {
        if (bytes.Length != 4) throw new ArgumentException();
        return new DateTime(1904, 1, 1, 0, 0, 0, DateTimeKind.Local).AddSeconds(
                  BitConverter.ToUInt32(bytes, 0));
    }
Run Code Online (Sandbox Code Playgroud)

用你的价值测试它:

    var date5 = DateReaders.ConvertHFSDate(DateReaders.ReadBytes(
                   new MemoryStream(new byte[] {0xCD,0x4E,0x55,0xC3 }), 4, true));
Run Code Online (Sandbox Code Playgroud)

产生{11/5/2007 10:50:53 PM}