time-decode 7.0.2__tar.gz → 7.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {time-decode-7.0.2/time_decode.egg-info → time_decode-7.1.0}/PKG-INFO +3 -1
- {time-decode-7.0.2 → time_decode-7.1.0}/README.md +2 -0
- {time-decode-7.0.2 → time_decode-7.1.0}/pyproject.toml +1 -1
- {time-decode-7.0.2 → time_decode-7.1.0}/time_decode/time_decode.py +115 -4
- {time-decode-7.0.2 → time_decode-7.1.0/time_decode.egg-info}/PKG-INFO +3 -1
- {time-decode-7.0.2 → time_decode-7.1.0}/LICENSE +0 -0
- {time-decode-7.0.2 → time_decode-7.1.0}/setup.cfg +0 -0
- {time-decode-7.0.2 → time_decode-7.1.0}/time_decode/__init__.py +0 -0
- {time-decode-7.0.2 → time_decode-7.1.0}/time_decode.egg-info/SOURCES.txt +0 -0
- {time-decode-7.0.2 → time_decode-7.1.0}/time_decode.egg-info/dependency_links.txt +0 -0
- {time-decode-7.0.2 → time_decode-7.1.0}/time_decode.egg-info/entry_points.txt +0 -0
- {time-decode-7.0.2 → time_decode-7.1.0}/time_decode.egg-info/requires.txt +0 -0
- {time-decode-7.0.2 → time_decode-7.1.0}/time_decode.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: time-decode
|
|
3
|
-
Version: 7.0
|
|
3
|
+
Version: 7.1.0
|
|
4
4
|
Summary: Python 3 timestamp decode/encode tool
|
|
5
5
|
Author-email: "Corey Forman (digitalsleuth)" <github@digitalsleuth.ca>
|
|
6
6
|
Maintainer-email: "Corey Forman (digitalsleuth)" <github@digitalsleuth.ca>
|
|
@@ -63,6 +63,7 @@ This python script provides the following conversions from existing timestamps:
|
|
|
63
63
|
- 128-bit SYSTEMTIME
|
|
64
64
|
- 32-bit MS-DOS time, result is Local
|
|
65
65
|
- Active Directory value
|
|
66
|
+
- Apache Cookie
|
|
66
67
|
- Apple Biome 64-bit decimal format
|
|
67
68
|
- Apple Biome hex format
|
|
68
69
|
- Bitwise decimal 10-digit
|
|
@@ -85,6 +86,7 @@ This python script provides the following conversions from existing timestamps:
|
|
|
85
86
|
- iOS 11+ (as NSDate)
|
|
86
87
|
- KSUID 27-character
|
|
87
88
|
- KSUID 9-digit
|
|
89
|
+
- LEB128 hex value
|
|
88
90
|
- Mac Absolute Time (as NSDate)
|
|
89
91
|
- Mac OS/HFS+ Decimal Time
|
|
90
92
|
- Mastodon URL
|
|
@@ -21,6 +21,7 @@ This python script provides the following conversions from existing timestamps:
|
|
|
21
21
|
- 128-bit SYSTEMTIME
|
|
22
22
|
- 32-bit MS-DOS time, result is Local
|
|
23
23
|
- Active Directory value
|
|
24
|
+
- Apache Cookie
|
|
24
25
|
- Apple Biome 64-bit decimal format
|
|
25
26
|
- Apple Biome hex format
|
|
26
27
|
- Bitwise decimal 10-digit
|
|
@@ -43,6 +44,7 @@ This python script provides the following conversions from existing timestamps:
|
|
|
43
44
|
- iOS 11+ (as NSDate)
|
|
44
45
|
- KSUID 27-character
|
|
45
46
|
- KSUID 9-digit
|
|
47
|
+
- LEB128 hex value
|
|
46
48
|
- Mac Absolute Time (as NSDate)
|
|
47
49
|
- Mac OS/HFS+ Decimal Time
|
|
48
50
|
- Mastodon URL
|
|
@@ -49,8 +49,8 @@ from PyQt6.QtWidgets import (
|
|
|
49
49
|
init(autoreset=True)
|
|
50
50
|
|
|
51
51
|
__author__ = "Corey Forman (digitalsleuth)"
|
|
52
|
-
__date__ = "
|
|
53
|
-
__version__ = "7.0
|
|
52
|
+
__date__ = "24 Jun 2024"
|
|
53
|
+
__version__ = "7.1.0"
|
|
54
54
|
__description__ = "Python 3 CLI Date Time Conversion Tool"
|
|
55
55
|
__fmt__ = "%Y-%m-%d %H:%M:%S.%f"
|
|
56
56
|
__red__ = "\033[1;31m"
|
|
@@ -1012,6 +1012,16 @@ ts_types = {
|
|
|
1012
1012
|
"S32 encoded (Bluesky) timestamps are 9 characters long",
|
|
1013
1013
|
"3kzgbkpsk",
|
|
1014
1014
|
],
|
|
1015
|
+
"apache": [
|
|
1016
|
+
"Apache Cookie Hex time",
|
|
1017
|
+
"Apache Cookie hex timestamps are 13 hex characters long",
|
|
1018
|
+
"5faa420b70880",
|
|
1019
|
+
],
|
|
1020
|
+
"leb128_hex": [
|
|
1021
|
+
"LEB128 Hex time",
|
|
1022
|
+
"LEB128 Hex timestamps are variable-length and even-length",
|
|
1023
|
+
"8ed1b7b8fd30",
|
|
1024
|
+
],
|
|
1015
1025
|
}
|
|
1016
1026
|
__types__ = len(ts_types)
|
|
1017
1027
|
|
|
@@ -1377,7 +1387,7 @@ def from_ad(timestamp):
|
|
|
1377
1387
|
)
|
|
1378
1388
|
in_ad = dt_obj.strftime(__fmt__)
|
|
1379
1389
|
indiv_output = str(f"{ts_type}: {in_ad} UTC")
|
|
1380
|
-
combined_output = str(f"{__red__}{ts_type}:\t{in_ad} UTC{__clr__}")
|
|
1390
|
+
combined_output = str(f"{__red__}{ts_type}:\t\t{in_ad} UTC{__clr__}")
|
|
1381
1391
|
except Exception:
|
|
1382
1392
|
handle(sys.exc_info())
|
|
1383
1393
|
in_ad = indiv_output = combined_output = False
|
|
@@ -3822,12 +3832,102 @@ def to_s32(dt_val):
|
|
|
3822
3832
|
unix_mil = math.floor(unix_mil / 32)
|
|
3823
3833
|
result = S32_CHARS[index] + result
|
|
3824
3834
|
out_s32 = result
|
|
3825
|
-
ts_output = str(f"{ts_type}:\t
|
|
3835
|
+
ts_output = str(f"{ts_type}:\t{out_s32}")
|
|
3826
3836
|
except Exception:
|
|
3827
3837
|
handle(sys.exc_info())
|
|
3828
3838
|
out_s32 = ts_output = False
|
|
3829
3839
|
return out_s32, ts_output
|
|
3830
3840
|
|
|
3841
|
+
def from_apache(timestamp):
|
|
3842
|
+
"""Convert an Apache hex timestamp to a date/time value"""
|
|
3843
|
+
"""This value has 13 hex characters, and does not fit a byte boundary"""
|
|
3844
|
+
ts_type, reason, _ = ts_types["apache"]
|
|
3845
|
+
try:
|
|
3846
|
+
timestamp = str(timestamp)
|
|
3847
|
+
if len(timestamp) != 13 or not all(char in hexdigits for char in timestamp):
|
|
3848
|
+
in_apache = indiv_output = combined_output = False
|
|
3849
|
+
else:
|
|
3850
|
+
dec_val = int(timestamp, 16)
|
|
3851
|
+
dt_obj = epochs[1970] + timedelta(microseconds=dec_val)
|
|
3852
|
+
in_apache = dt_obj.strftime(__fmt__)
|
|
3853
|
+
indiv_output = str(f"{ts_type}: {in_apache} UTC")
|
|
3854
|
+
combined_output = str(f"{__red__}{ts_type}:\t\t{in_apache} UTC{__clr__}")
|
|
3855
|
+
except Exception:
|
|
3856
|
+
handle(sys.exc_info())
|
|
3857
|
+
in_apache = indiv_output = combined_output = False
|
|
3858
|
+
return in_apache, indiv_output, combined_output, reason
|
|
3859
|
+
|
|
3860
|
+
def to_apache(dt_val):
|
|
3861
|
+
"""Convert a date/time to an Apache cookie value"""
|
|
3862
|
+
ts_type, _, _ = ts_types["apache"]
|
|
3863
|
+
try:
|
|
3864
|
+
dt_obj = duparser.parse(dt_val)
|
|
3865
|
+
if hasattr(dt_obj.tzinfo, "_offset"):
|
|
3866
|
+
dt_tz = dt_obj.tzinfo._offset.total_seconds()
|
|
3867
|
+
else:
|
|
3868
|
+
dt_tz = 0
|
|
3869
|
+
dt_object = duparser.parse(dt_val, ignoretz=True)
|
|
3870
|
+
apache_int = int(((dt_obj - epochs[1970]).total_seconds() - int(dt_tz)) * 1000000)
|
|
3871
|
+
out_apache = f"{apache_int:x}"
|
|
3872
|
+
ts_output = str(f"{ts_type}:\t\t{out_apache}")
|
|
3873
|
+
except Exception:
|
|
3874
|
+
handle(sys.exc_info())
|
|
3875
|
+
out_apache = ts_output = False
|
|
3876
|
+
return out_apache, ts_output
|
|
3877
|
+
|
|
3878
|
+
def to_leb128_hex(dt_val):
|
|
3879
|
+
"""Convert a date to a LEB128 hex value."""
|
|
3880
|
+
ts_type, _, _ = ts_types["leb128_hex"]
|
|
3881
|
+
try:
|
|
3882
|
+
dt_obj = duparser.parse(dt_val)
|
|
3883
|
+
if hasattr(dt_obj.tzinfo, "_offset"):
|
|
3884
|
+
dt_tz = dt_obj.tzinfo._offset.total_seconds()
|
|
3885
|
+
else:
|
|
3886
|
+
dt_tz = 0
|
|
3887
|
+
dt_obj = duparser.parse(dt_val, ignoretz=True)
|
|
3888
|
+
unix_milli, _ = to_unix_milli(str(dt_obj))
|
|
3889
|
+
unix_milli = int(unix_milli)
|
|
3890
|
+
byte_list = []
|
|
3891
|
+
while True:
|
|
3892
|
+
byte_val = unix_milli & 0x7F
|
|
3893
|
+
unix_milli >>= 7
|
|
3894
|
+
if unix_milli != 0:
|
|
3895
|
+
byte_val |= 0x80
|
|
3896
|
+
byte_list.append(byte_val)
|
|
3897
|
+
if unix_milli == 0:
|
|
3898
|
+
break
|
|
3899
|
+
out_leb128_hex = ''.join([f"{byte_val:02x}" for byte_val in byte_list])
|
|
3900
|
+
ts_output = str(f"{ts_type}:\t\t{out_leb128_hex}")
|
|
3901
|
+
except Exception:
|
|
3902
|
+
handle(sys.exc_info())
|
|
3903
|
+
out_leb128_hex = ts_output = False
|
|
3904
|
+
return out_leb128_hex, ts_output
|
|
3905
|
+
|
|
3906
|
+
def from_leb128_hex(timestamp):
|
|
3907
|
+
"""Convert a LEB 128 hex value to a date"""
|
|
3908
|
+
ts_type, reason, _ = ts_types["leb128_hex"]
|
|
3909
|
+
try:
|
|
3910
|
+
if not len(timestamp) % 2 == 0 or not all(char in hexdigits for char in timestamp):
|
|
3911
|
+
in_leb128_hex = indiv_output = combined_output = False
|
|
3912
|
+
else:
|
|
3913
|
+
ts_hex_list = [(timestamp[i:i+2]) for i in range(0, len(timestamp), 2)]
|
|
3914
|
+
unix_milli = 0
|
|
3915
|
+
shift = 0
|
|
3916
|
+
for hex_val in ts_hex_list:
|
|
3917
|
+
byte_val = int(hex_val, 16)
|
|
3918
|
+
unix_milli |= (byte_val & 0x7F) << shift
|
|
3919
|
+
if (byte_val & 0x80) == 0:
|
|
3920
|
+
break
|
|
3921
|
+
shift += 7
|
|
3922
|
+
in_leb128_hex, _, _, _ = from_unix_milli(str(unix_milli))
|
|
3923
|
+
indiv_output = str(f"{ts_type}: {in_leb128_hex} UTC")
|
|
3924
|
+
combined_output = str(
|
|
3925
|
+
f"{__red__}{ts_type}:\t\t{in_leb128_hex} UTC{__clr__}"
|
|
3926
|
+
)
|
|
3927
|
+
except Exception:
|
|
3928
|
+
handle(sys.exc_info())
|
|
3929
|
+
in_leb128_hex = indiv_output = combined_output = False
|
|
3930
|
+
return in_leb128_hex, indiv_output, combined_output, reason
|
|
3831
3931
|
|
|
3832
3932
|
def date_range(start, end, check_date):
|
|
3833
3933
|
"""Check if date is in range of start and end, return True if it is"""
|
|
@@ -3922,9 +4022,12 @@ single_funcs = {
|
|
|
3922
4022
|
"biome64": from_biome64,
|
|
3923
4023
|
"biomehex": from_biomehex,
|
|
3924
4024
|
"s32": from_s32,
|
|
4025
|
+
"apache": from_apache,
|
|
4026
|
+
"leb128": from_leb128_hex,
|
|
3925
4027
|
}
|
|
3926
4028
|
from_funcs = [
|
|
3927
4029
|
from_ad,
|
|
4030
|
+
from_apache,
|
|
3928
4031
|
from_biome64,
|
|
3929
4032
|
from_biomehex,
|
|
3930
4033
|
from_bitdate,
|
|
@@ -3947,6 +4050,7 @@ from_funcs = [
|
|
|
3947
4050
|
from_mac,
|
|
3948
4051
|
from_ksalnum,
|
|
3949
4052
|
from_ksdec,
|
|
4053
|
+
from_leb128_hex,
|
|
3950
4054
|
from_hfs_dec,
|
|
3951
4055
|
from_mastodon,
|
|
3952
4056
|
from_metasploit,
|
|
@@ -3982,6 +4086,7 @@ from_funcs = [
|
|
|
3982
4086
|
]
|
|
3983
4087
|
to_funcs = [
|
|
3984
4088
|
to_ad,
|
|
4089
|
+
to_apache,
|
|
3985
4090
|
to_biome64,
|
|
3986
4091
|
to_biomehex,
|
|
3987
4092
|
to_bitdate,
|
|
@@ -3998,6 +4103,7 @@ to_funcs = [
|
|
|
3998
4103
|
to_hfs_be,
|
|
3999
4104
|
to_hfs_le,
|
|
4000
4105
|
to_ksdec,
|
|
4106
|
+
to_leb128_hex,
|
|
4001
4107
|
to_hfs_dec,
|
|
4002
4108
|
to_mastodon,
|
|
4003
4109
|
to_systemtime,
|
|
@@ -4065,6 +4171,9 @@ def main():
|
|
|
4065
4171
|
arg_parse.add_argument(
|
|
4066
4172
|
"--active", metavar="", help="convert from Active Directory value"
|
|
4067
4173
|
)
|
|
4174
|
+
arg_parse.add_argument(
|
|
4175
|
+
"--apache", metavar="", help="convert from an Apache Cookie hex value"
|
|
4176
|
+
)
|
|
4068
4177
|
arg_parse.add_argument(
|
|
4069
4178
|
"--auto", metavar="", help="convert from OLE Automation Date format"
|
|
4070
4179
|
)
|
|
@@ -4133,6 +4242,8 @@ def main():
|
|
|
4133
4242
|
arg_parse.add_argument(
|
|
4134
4243
|
"--ksalnum", metavar="", help="convert from a KSUID 27-character value"
|
|
4135
4244
|
)
|
|
4245
|
+
arg_parse.add_argument(
|
|
4246
|
+
"--leb128", metavar="", help="convert from a LEB128 hex value")
|
|
4136
4247
|
arg_parse.add_argument("--mac", metavar="", help="convert from Mac Absolute Time")
|
|
4137
4248
|
arg_parse.add_argument(
|
|
4138
4249
|
"--mastodon", metavar="", help="convert from a Mastodon URL value"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: time-decode
|
|
3
|
-
Version: 7.0
|
|
3
|
+
Version: 7.1.0
|
|
4
4
|
Summary: Python 3 timestamp decode/encode tool
|
|
5
5
|
Author-email: "Corey Forman (digitalsleuth)" <github@digitalsleuth.ca>
|
|
6
6
|
Maintainer-email: "Corey Forman (digitalsleuth)" <github@digitalsleuth.ca>
|
|
@@ -63,6 +63,7 @@ This python script provides the following conversions from existing timestamps:
|
|
|
63
63
|
- 128-bit SYSTEMTIME
|
|
64
64
|
- 32-bit MS-DOS time, result is Local
|
|
65
65
|
- Active Directory value
|
|
66
|
+
- Apache Cookie
|
|
66
67
|
- Apple Biome 64-bit decimal format
|
|
67
68
|
- Apple Biome hex format
|
|
68
69
|
- Bitwise decimal 10-digit
|
|
@@ -85,6 +86,7 @@ This python script provides the following conversions from existing timestamps:
|
|
|
85
86
|
- iOS 11+ (as NSDate)
|
|
86
87
|
- KSUID 27-character
|
|
87
88
|
- KSUID 9-digit
|
|
89
|
+
- LEB128 hex value
|
|
88
90
|
- Mac Absolute Time (as NSDate)
|
|
89
91
|
- Mac OS/HFS+ Decimal Time
|
|
90
92
|
- Mastodon URL
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|