Как файл может быть «создан» в 1641 году?

75

Несколько лет назад я наткнулся на этот файл на нашем файловом сервере.

Снимок экрана: диалоговое окно свойств файла в Microsoft Windows

И мне интересно, как файл может сказать, что он был создан в 1641 году? Насколько я знаю, время на ПК определяется числом секунд с 1 января 1970 года. Если этот индекс не работает, вы можете получить 31 декабря 1969 года (индекс, вероятно, говорит -1), но я озадачен этим на первый взгляд случайная дата, предшествующая даже основанию Соединенных Штатов Америки.

Так как же можно датировать файл 1641 годом?

PS: даты на французском. Февраль февраль.

Fredy31
источник
29
«Насколько я знаю, время на ПК определяется количеством секунд с 1 января 1970 года». - Даже для систем, где это так, даты до 1970 года легко представить, сделав это число (известное как метка времени Unix ) отрицательным. Например, unix time -1000000000 соответствует 1938-04-24 22:33:20.
marcelm
1
@marcelm Да, но минимально возможная дата существует в 1901 году из-за ограниченного диапазона 32-битных целых чисел.
slhck
14
@slhck: Я думаю, что Марсельм использовал 64-битную временную метку, потому что это то, что используют нынешние файловые системы Unix / Linux, ядра и программное обеспечение пользовательского пространства. См. clock_gettime(2)Справочную страницу для определения того struct timespec, что statи другие системные вызовы используют для передачи временных меток между пользовательским пространством и ядром. Это структура с time_tсекундами и long tv_nsecнаносекундами. В 64-битных системах обе являются 64-битными, поэтому общая метка времени составляет 128 бит (16 байтов). (Извините за слишком много деталей, я увлекся.)
Питер Кордес
3
Вы получили хороший ответ на вопрос о том, как дата в 1600-х годах может быть проставлена ​​в файле, теперь пришло время задуматься о том, как это произошло. Я бы внимательно посмотрел содержимое этого wp-файла, чтобы увидеть, что могло быть добавлено, поскольку это могло бы пролить свет на то, как это произошло. Я бы посмотрел на установленные плагины и подтвердил, что ни один из них не тенистый Я думаю, что-то изменило этот файл и попытался вручную пометить измененные / созданные даты, чтобы скрыть, что файл был изменен, но указал время Unix вместо времени Windows.
Томас Карлайл
2
Король Людовик XIII Справедливый демонстрировал приверженность королевской линии PHP?
Джесси Слайсер

Ответы:

106

Почему возможно свидание 1600-х годов?

Windows не хранит метки времени изменения файлов, как в системах Unix . По данным Windows Dev Center (выделено мое):

Время файла - это 64-разрядное значение, представляющее число интервалов в 100 наносекунд , прошедших с 12:00 1 января 1601 года. Всемирное координированное время (UTC). Система записывает время файлов, когда приложения создают, получают доступ и записывают в файлы.

Таким образом, установив неправильное значение здесь, вы можете легко получить даты 1600-х годов.

Конечно, еще один важный вопрос: как было установлено это значение? Какая фактическая дата? Я думаю, вы никогда не сможете это выяснить, поскольку это могло быть просто ошибкой вычисления в драйвере файловой системы. Другой ответ предполагает, что дата на самом деле является меткой времени Unix, интерпретируемой как метка времени Windows, но на самом деле они рассчитываются на разных интервалах (секунды по сравнению с наносекундами).

Как это связано с проблемой 2038 года?

Использование 64-битного типа данных означает, что Windows (как правило) не подвержена проблеме 2038 года, которая существует в традиционных системах Unix, поскольку Unix изначально использовала 32-битное целое число, которое переполняется раньше, чем 64-битное целое число, которое Windows есть. (Это несмотря на то, что Unix работает за секунды, а Windows - за микро / наносекунды.)

Конечно, Windows по-прежнему подвержена влиянию 32-битных программ, скомпилированных со старыми версиями Visual Studio.

Более новые операционные системы Unix уже расширили тип данных до 64 бит, что позволило избежать этой проблемы. (Фактически, поскольку временные метки Unix работают в секундах, новая дата оборота будет через 292 миллиарда лет.)

Какую максимальную дату можно установить?

Для любопытных - вот как это вычислить:

  • Число возможных значений в 64-битовое целое число в 2 63 - 1 = 9223372036854775807 .
  • Каждый тик представляет 100 наносекунд, что составляет 0,1 мкс или 0,0000001 с.
  • Максимальный диапазон времени будет 9223372036854775807 ⨉ 0,0000001 с , то есть сотни миллиардов секунд.
  • Один час имеет 3600 секунд, один день имеет 86400 секунд, а один год имеет 365 дней, поэтому в году 86400 × 365 с = 31536000 с . Это, конечно, только среднее значение, игнорируя високосные годы, високосные секунды или любые изменения в календаре, которые будущие постапокалиптические режимы могут диктовать оставшимся землянам.
  • 9223372036854775807 ⨉ 0,0000001 с / 31536000 с ≈ 29247 лет
  • @corsiKaобъясняет, как мы можем вычесть високосные годы: 29247/365/4 ≈ 20
  • Таким образом, ваш максимальный год составляет 1601 + 29247 - 20 = 30828 .

Некоторые люди действительно пытались установить это и придумали тот же год.

slhck
источник
7
Напомним, что Unix (или, по крайней мере, Linux) уже решил проблему 2038 для ядра / файловых систем на 64-битных архитектурах, где time_tиспользуется 64-битный тип, поэтому, надеюсь, приложения используют time_tвместо целочисленного типа, который все еще 32-битный, и будет обрезать временные метки ... В любом случае, если кому-то будет интересно узнать о состоянии проблемы, она в основном решена, за исключением устаревших 32-битных. IDK, если 32-битный ARM будет по-прежнему актуален в 2038 году, но это вызовет как минимум изменение ABI. 32-разрядная версия x86 практически исчезла из мира Unix; это только Windows, где 32-битный код все еще распространен.
Питер Кордес,
Комментарии не для расширенного обсуждения; этот разговор был перенесен в чат .
подмастерье Компьютерщик
1
Время VMS - это « 64-битное значение, которое представляет количество интервалов в 100 наносекунд, прошедших с 17 ноября 1858 года. :)
RonJohn
Год 30k ... удивительно низкий
Джон Дворак
2
@DonaldDuck blogs.msdn.microsoft.com/oldnewthing/20090306-00/?p=18913 и около 1600 человек все еще использовали юлианский календарь, делая представление любой даты до этого более сложным.
Мацей Пехотка
16

Если вы не слишком расстроились из-за некоторых догадок, позвольте мне предложить объяснение. И я не имею в виду «кто-то установил значение ерунды», это всегда возможно :)

Время Unix обычно использует количество секунд с 1970 года. Windows, с другой стороны, использует 1601 в качестве начального года. Поэтому, если мы предположим (и это большое предположение!), Что проблема заключается в неправильном преобразовании между этими двумя временами, мы можем представить, что дата, которая должна была быть представлена, фактически когда-то в 2011 году (1970 + 41), которая была неправильно преобразована до 1640 (1601 + 41) . РЕДАКТИРОВАТЬ: На самом деле, я сделал ошибку в Windows, начиная с года. Вполне возможно, что фактическое время создания было в 2010 году, или произошла другая ошибка (отдельные ошибки часто встречаются в программном обеспечении: D).

Учитывая, что в этом году произошла еще одна из дат отслеживания, связанных с данным файлом, я думаю, что это довольно правдоподобное объяснение :)

Luaan
источник
Так может быть, что дата была написана в Unix, но читается в UTC?
Fredy31
Windows использует 1601, а не 1600.
Joey
3
Несколько проблем с этой теорией: Согласно скриншоту, файл был бы создан через 11 дней после последнего обращения к нему. Кроме того, временные метки Windows считаются за 100 наносекунд, а UNIX - за секунды.
Нолонар
2
@ Джо-тьфу, моя ошибка. Это делает подгонку намного хуже, чем на первый взгляд :) Я думаю, что та же самая основная идея все еще должна работать, но, вероятно, ошибок больше, чем я предполагал. Или, конечно, файл был создан в 2010 году, а не в 2011 году.
Luaan
2
Секунды между эпохой Windows и отображаемым временем и датой файла составляют 1.266.705.294 . При добавлении в эпоху Unix это приводит к 2010-02-20 23:34:54 CEST , который был субботой.
SQB
5

Как было написано другими, эпоха Windows в 1601-01-01 00:00 .

Количество секунд между этой эпохой и отображаемым временем файла составляет 1,266,705,294 .
Если мы добавим это к эпохе Unix, мы прибудем в субботу, 2010-02-20 23:34:54 CEST . Это примерно за год до последней даты доступа, что делает его несколько правдоподобным. Так что, возможно, это была временная метка Unix, интерпретируемая против неправильной эпохи.

SQB
источник
Как ни странно, эпоха .NET - 0001-01-01 00:00 UTC (что на 1600 лет раньше). См msdn.microsoft.com/en-us/library/...
Наюки
2

Как обычно для таких вопросов, в блоге Рэймонда Чена есть ответ на этот вопрос из «Почему эпоха Win32 1 января 1601 года?» запись от 6 марта 2009 года:

FILETIMEСтруктура записывает время в виде 100-наносекундных интервалов с 1 января 1601. Почему эта дата выбрана?

Григорианский календарь работает по 400-летнему циклу, и 1601 год - это первый год цикла, который был активен во время разработки Windows NT. Другими словами, это было выбрано для того, чтобы математика получилась красивой.

На самом деле у меня есть электронное письмо от Дейва Катлера, подтверждающее это.

ErikF
источник