问题描述
我从游戏中捕获了这种 64 位时间格式并试图理解它。 我不能使用日期增量,因为值时不时地完全改变,甚至变成负数,如下所示。
v1:int64=-5990085973098618987; //2021-01-25 13:30:00
v2:int64=-5990085973321147595; //4 mins later
v3:int64=6140958949625363349; //7 mins later
v4:int64=6140958948894898101; //11 mins later
v5:int64=-174740204032730139; //16 mins later
v6:int64=-174740204054383467; //18 mins later
v7:int64=-6490439358095090795; //23 mins later
我尝试将 64 位拆分为两个 32 位容器以获取低部分和高部分。还是奇怪的价值观。 我也尝试使用 pdouble(@value)^ 来获取 64 位数据的浮点值,仍然是奇怪的值。 很多想法都用完了,也许是某种位域数据或其他正在发生的事情。
hipart: -1394675573 | lopart: 1466441621 | hex: acdef08b|57681f95 | swap: -7701322112560996692
hipart: -1394675573 | lopart: 1243913013 | hex: acdef08b|4a249b35 | swap: 3862721007994330796
hipart: 1429803424 | lopart: -458425451 | hex: 553911a0|e4acfb95 | swap: -7639322244965910187
hipart: 1429803424 | lopart: -1188890699 | hex: 553911a0|b922f7b5 | swap: -5334757052947285675
hipart: -40684875 | lopart: -760849435 | hex: fd9332b5|d2a65be5 | swap: -1919757392230050819
hipart: -40684875 | lopart: -782502763 | hex: fd9332b5|d15bf495 | swap: -7641381711494605827
hipart: -1511173174 | lopart: -1467540587 | hex: a5ed53ca|a8871b95 | swap: -7702413578668347995
欢迎任何想法,提前致谢 //mbs
--编辑:到目前为止,感谢 Martin Rosenau,我们能够像这样编码:
func mulproc_nfsw(i:int64;key:uint32):int64;
begin
if (blnk i) or (blnk key) then exit;
p:pointer=@i;
hi:uint32=uint32(p+4)^; //30864159 (hex: 01d6f31f)
lo:uint32=uint32(p)^; //748455936 (hex: 2c9c8800)
hi64:int64=hi*key; //0135b55a acdef08b <-- keep
lo64:int64=lo*key; //1d566e0b a65f2800 <-- keep
q:pointer=@result; //-5990085971773806592
uint32(q+4)^:=hi64; //acdef08b
uint32(q)^:=lo64; //a65f2800
end;
func encode_time_nfsw(j:juncture):int64;
begin
if blnk j then exit; //input: '2021-01-25 13:37:07'
key:uint32=$A85A2115; //encode key
ft:int64=j.filetime; //hex: 01d6f31f 2c9c8800
result:=mulproc_nfsw(ft,key);
end;
--EDIT2:最后,感谢 fpiette,我们也能够解码:
func decode_time_nfsw(i:int64):juncture;
begin
if blnk i then exit; //input: -5990085971773806592
key:uint32=$3069263D; //decode key
ft:int64=mulproc_nfsw(i,key);
result.setfiletime(ft);
end;
解决方法
我检查了我的怀疑,即高 32 位和低 32 位只是简单地乘以 A85A2115(十六进制):
我们得到一个 FILETIME 结构。然后我们独立地执行高字和低字的 32x32->32 位乘法(这意味着我们丢弃 64 位结果的高 32 位)。
示例:
25 Jan 2021 13:37:07 (and some milliseconds)
未加密的文件时间:
High dword = 1D6F31F (hex)
Low dword = 2C9CA481 (hex)
乘法
High dword: 1D6F31F * A85A2115 = 135B55AACDEF08B (hex)
Low dword: 2C9CA481 * A85A2115 = 1D5680CA57681F95 (hex)
现在只取结果的低 32 位:
High dword: ACDEF08B (hex)
Low dword: 57681F95 (hex)
不幸的是,我不知道如何做“反向操作”;我通过使用以下伪代码在循环中搜索结果来做到这一点:
encryptedValue = 57681F95 (hex)
originalValue = 0
product = 0
while product not equal to encryptedValue
// 32-bit addition discarding carry:
product = product + A85A2115 (hex)
originalValue = originalValue + 1
end_of_while_loop
我们得到以下结果:
25 Jan 2021 13:37:07 => acdef08b|57681f95
25 Jan 2021 13:40:51 => acdef08b|4a249b35
25 Jan 2021 13:45:07 => 553911a0|e4acfb95
25 Jan 2021 13:49:03 => 553911a0|b922f7b5
25 Jan 2021 13:53:53 => fd9332b5|d2a65be5
25 Jan 2021 13:55:50 => fd9332b5|d15bf495
25 Jan 2021 14:00:39 => a5ed53ca|a8871b95
附录
相反的操作似乎是通过乘以 3069263D(十六进制)来完成的(并且只使用低 32 位)。
加密:
2C9CA481 * A85A2115 = 1D5680CA57681F95
=> Result: 57681F95
解密:
57681F95 * 3069263D = 10876CAF2C9CA481
=> Result: 2C9CA481