Jak można „utworzyć” plik w 1641 roku?

75

Kilka lat temu natknąłem się na ten plik na naszym serwerze plików.

Zrzut ekranu okna dialogowego właściwości pliku w systemie Microsoft Windows

Zastanawiam się, jak plik może powiedzieć, że został utworzony w 1641 roku? O ile mi wiadomo, czas na PC jest definiowany przez liczbę sekund od 1 stycznia 1970 roku. Jeśli ten indeks się zepsuje, możesz dostać 31 grudnia 1969 roku (indeks prawdopodobnie mówi -1), ale jestem tym zaskoczony pozornie przypadkowa data, która wyprzedza nawet powstanie Stanów Zjednoczonych Ameryki.

Jak więc można datować plik w 1641 roku?

PS: Daty są w języku francuskim. Février to luty.

Fredy31
źródło
29
„O ile mi wiadomo, czas na komputerze jest definiowany przez liczbę sekund od 1 stycznia 1970 r.” - Nawet w systemach, w których jest, daty przed 1970 r. Można łatwo przedstawić, czyniąc tę ​​liczbę (znaną jako uniksowy znacznik czasu ) ujemną. Na przykład czas uniksowy -1000000000 odpowiada 1938-04-24 22:33:20.
marcelm
1
@marcelm Tak, ale minimalną możliwą datą jest rok 1901 z powodu ograniczonego zakresu 32-bitowych liczb całkowitych.
slhck
14
@slhck: Wydaje mi się, że marcelm zakładał 64-bitowy znacznik czasu, ponieważ tego właśnie używają obecne systemy plików, jądra i oprogramowanie użytkownika w przestrzeni Unix / Linux. Zobacz clock_gettime(2)stronę podręcznika, aby uzyskać definicję tego struct timespec, czego statużywają inne wywołania systemowe do przekazywania znaczników czasu między przestrzenią użytkownika a jądrem. Jest to struktura z time_tsekundami i long tv_nsecnanosekundami. W systemach 64-bitowych oba są 64-bitowe, więc cały znacznik czasu wynosi 128 bitów (16 bajtów). (Przepraszam za zbyt wiele szczegółów, dałem się ponieść emocjom.)
Peter Cordes
3
Masz dobrą odpowiedź na to, jak data z 1600 roku może być stemplowana do pliku, teraz nadszedł czas, aby zastanowić się, jak to się stało. Przyjrzałbym się uważnie zawartości tego pliku wp, aby zobaczyć, co mogło zostać dodane, ponieważ mogłoby to rzucić światło na to, jak to się stało. Patrzę na zainstalowane wtyczki i sprawdzam, czy żadne nie są podejrzane. Myślę, że coś zmodyfikowało ten plik i próbowałem ręcznie stemplować zmodyfikowane / utworzone daty, aby ukryć, że plik został zmodyfikowany, ale określono czas uniksowy zamiast czasu systemu Windows.
Thomas Carlisle
2
Król Ludwik XIII Sprawiedliwy demonstrował zaangażowanie linii królewskiej w PHP?
Jesse Slicer

Odpowiedzi:

106

Dlaczego możliwa jest data z 1600 roku?

System Windows nie przechowuje znaczników czasu modyfikacji plików, tak jak robią to systemy uniksowe . Według Windows Dev Center (moje podkreślenie):

Czas pliku to 64-bitowa wartość, która reprezentuje liczbę 100 nanosekundowych interwałów, które upłynęły od godziny 12:00 1 stycznia 1601 Uniwersalny czas koordynowany (UTC). System rejestruje czasy plików, gdy aplikacje tworzą, uzyskują dostęp i zapisują pliki.

Tak więc, ustawiając tutaj niewłaściwą wartość, możesz łatwo uzyskać daty z XVII wieku.

Oczywiście kolejnym ważnym pytaniem jest: w jaki sposób ustawiono tę wartość? Jaka jest rzeczywista data? Myślę, że nigdy nie będziesz w stanie się dowiedzieć, ponieważ mógł to być po prostu błąd obliczeniowy w sterowniku systemu plików. Inna odpowiedź zakłada hipotezę, że data jest w rzeczywistości uniksowym znacznikiem czasu interpretowanym jako znacznik czasu systemu Windows, ale w rzeczywistości są one obliczane w różnych odstępach czasu (sekundy w porównaniu do nanosekund).

Jak to się ma do problemu z 2038 r.?

Zastosowanie 64-bitowego typu danych oznacza, że ​​na system Windows (ogólnie) nie ma wpływu problem z rokiem 2038 występujący w tradycyjnych systemach uniksowych, ponieważ Unix początkowo używał 32-bitowej liczby całkowitej, która przepełnia się wcześniej niż 64-bitowa liczba całkowita tego systemu Windows ma. (Dzieje się tak pomimo tego, że Unix działa w kilka sekund, a Windows w mikro / nanosekundach.)

Oczywiście Windows nadal ma wpływ na używanie 32-bitowych programów, które zostały skompilowane ze starszymi wersjami Visual Studio.

Nowsze systemy operacyjne Unix już rozszerzyły typ danych do 64 bitów, unikając w ten sposób problemu. (W rzeczywistości, ponieważ uniksowe znaczniki czasu działają w kilka sekund, nowa data zakończenia będzie za 292 miliardów lat.)

Jaka jest maksymalna data, którą można ustawić?

Dla ciekawskich - oto jak to obliczyć:

  • Liczba możliwych wartości w 64-bitową liczbę całkowitą2 63 - 1 = 9223372036854775807 .
  • Każdy tik reprezentuje 100 nanosekund, co stanowi 0,1 µs lub 0,0000001 s.
  • Maksymalny zakres czasu wynosiłby 9223372036854775807 ⨉ 0,0000001 s , a więc setki miliardów sekund.
  • Jedna godzina ma 3600 sekund, jeden dzień ma 86400 sekund, a jeden rok ma 365 dni, więc jest 86400 ⨉ 365 s = 31536000 s w ciągu roku. Jest to oczywiście tylko średnia, ignorująca lata przestępne, sekundy przestępne lub wszelkie zmiany kalendarza, które przyszłe postapokaliptyczne reżimy mogą narzucić pozostałym ziemianom.
  • 9223372036854775807 ⨉ 0,0000001 s / 31536000 s ≈ 29247 lat
  • @corsiKawyjaśnia, w jaki sposób możemy odjąć lata przestępne: 29247/365/4 ≈ 20
  • Twój maksymalny rok to 1601 + 29247 - 20 = 30828 .

Niektórzy ludzie próbowali to ustalić i wymyślili ten sam rok.

slhck
źródło
7
Dla przypomnienia, Unix (lub przynajmniej Linux) już rozwiązał problem 2038 dla systemów jądra / plików w 64-bitowych architekturach, gdzie time_tjest to 64-bit, więc mam nadzieję, że aplikacje używają time_tzamiast typu całkowitego, który wciąż jest 32-bitowy i skróciłoby znaczniki czasu ... W każdym razie, gdyby ktoś był ciekawy stanu problemu, jest on w większości rozwiązany, z wyjątkiem starszej wersji 32-bitowej. IDK, jeśli 32-bitowy ARM będzie nadal odpowiedni w 2038 r., Ale wymusi to przynajmniej zmianę ABI. 32-bitowy x86 już prawie zniknął w świecie Uniksa; to tylko system Windows, w którym 32-bitowy kod jest nadal powszechny.
Peter Cordes
Komentarze nie są przeznaczone do rozszerzonej dyskusji; ta rozmowa została przeniesiona do czatu .
Journeyman Geek
1
Czas VMS to „ 64-bitowa wartość reprezentująca liczbę 100-nanosekundowych interwałów, które upłynęły od ” 17 listopada 1858 r. :)
RonJohn
Rok 30k jest ... zaskakująco niski
John Dvorak
2
@DonaldDuck blogs.msdn.microsoft.com/oldnewthing/20090306-00/?p=18913 i około 1600 osób nadal używało kalendarza juliańskiego, co utrudniało reprezentowanie dowolnej daty przed tym terminem.
Maciej Piechotka
16

Jeśli nie czujesz się tak źle z powodu zgadywania, pozwól, że wyjaśnię. I nie mam na myśli „ktoś ustawia wartość na nonsens”, to oczywiście zawsze możliwe :)

Czas uniksowy zwykle wykorzystuje liczbę sekund od 1970 roku. Z drugiej strony, Windows używa 1601 jako roku początkowego. Jeśli więc założymy (i to jest duże założenie!), Że problemem jest niewłaściwa konwersja między tymi dwoma czasami, możemy sobie wyobrazić, że data, która miała być reprezentowana, jest w rzeczywistości w 2011 r. (1970 + 41), która została niepoprawnie przekonwertowana do 1640 (1601 + 41) . EDYCJA: Właściwie popełniłem błąd w początkowym roku systemu Windows. Możliwe, że faktyczny czas utworzenia przypadał na 2010 r., Lub że wystąpił inny błąd (błędy indywidualne są dość powszechne w oprogramowaniu: D).

Biorąc pod uwagę, że ten rok jest kolejną datą śledzenia związaną z danym plikiem, myślę, że to całkiem prawdopodobne wytłumaczenie :)

Luaan
źródło
Więc może być tak, że data została napisana w Uniksie, ale czytana jest w UTC?
Fredy31
Windows używa 1601, a nie 1600.
Joey
3
Kilka problemów z tą teorią: Zgodnie ze zrzutem ekranu plik zostałby utworzony 11 dni po ostatnim dostępie. Ponadto znaczniki czasu systemu Windows są liczone w 100 nanosekundach, a czas UNIX w sekundach.
Nolonar
2
@Joey Ugh, mój błąd. To sprawia, że ​​dopasowanie jest znacznie gorsze niż na pierwszy rzut oka :) Myślę, że ten sam podstawowy pomysł powinien nadal działać, ale prawdopodobnie wiąże się to z większą liczbą błędów, niż się spodziewałem. Lub oczywiście plik został utworzony w 2010 r., A nie w 2011 r.
Luaan
2
Sekundy między epoką systemu Windows a wyświetloną datą / godziną pliku to 1.266.705.294 . Po dodaniu do epoki uniksowej daje to 2010-02-20 23:34:54 CEST , czyli sobotę.
SQB
5

Jak napisali inni, epoka Windowsa to 1601-01-01 00:00 .

Liczba sekund między wyświetloną epoką a czasem wyświetlania wynosi 1.266.705.294 .
Jeśli dodamy to do epoki Uniksa, osiągniemy w sobotę 2010-02-20 23:34:54 CEST . Jest to około rok przed datą ostatniego dostępu, co sprawia, że ​​jest to całkiem prawdopodobne. Być może był to uniksowy znacznik czasu interpretowany w odniesieniu do niewłaściwej epoki.

SQB
źródło
O dziwo, epoka .NET to 0001-01-01 00:00 UTC (czyli 1600 lat wcześniej). Zobacz msdn.microsoft.com/en-us/library/…
Nayuki
2

Jak zwykle w przypadku tego rodzaju pytań, blog Raymonda Chena ma na to odpowiedź z „Dlaczego epoka Win32 jest 1 stycznia 1601 roku?”. wpis od 6 marca 2009:

FILETIMEStruktura rejestruje czas w formie odstępach 100-nanosekundowych od 1 stycznia 1601. Dlaczego ta data wybrana?

Kalendarz gregoriański działa w cyklu 400-letnim, a 1601 to pierwszy rok cyklu, który był aktywny w czasie projektowania systemu Windows NT. Innymi słowy, wybrano, aby matematyka wyszła ładnie.

Tak naprawdę mam wiadomość od Dave'a Cutlera, która to potwierdza.

ErikF
źródło