我正在将一个C#函数复制到PHP。在C#中,GUID,DateTime和boolean被转换为字节。接下来,字节数组被合并和编码。最后一步是将其转换为base64。
以下部分存在字节数组:
GUID: 16 bytes
Timestamp: 8 bytes
Boolean: 1 byte
在php中,我已经转换了base64并将字符串解码回字节。我还设法将前16个字节转换为GUID。我验证了PHP返回的字节,它们是正确的。
现在我将8个字节转换为PHP中的时间戳。到目前为止我没有运气。我想问题是它返回一个int64。
C#
这是到datetime转换的C#字节数组:
public DateTime Timestamp;
......
byte[] timestamp_bytes = new byte[8];
input.Read(timestamp_bytes, 0, 8);
Timestamp = DateTime.FromBinary(System.BitConverter.ToInt64(timestamp_bytes, 0));
这是C#datetime到字节数组的转换:
public DateTime Timestamp;
......
byte[] timestamp_bytes = System.BitConverter.GetBytes(Timestamp.ToBinary());
当我输出Timestamp.ToString()时,我会在两种情况下得到 23-12-2011 09:54:56 。
PHP
在PHP中,我设法获得了8字节的十六进制:
$bin = pack("C*", 119, 23, 124, 173, 103, 143, 206, 136);
$hex = unpack("H*", $bin);
接下来我该怎么办?我已经尝试了一些转换方法,但我似乎从来没有得到正确的答案。
其他信息:
8个字节是:119,23,124,173,103,143,206,136
hexstring是:77177cad678fce88
我应该得到的日期时间:23-12-2011 09:54:56
php -r'echo PHP_INT_MAX;'返回9223372036854775807
C#应用程序不在我的权限范围内,所以我不能保证我可以改变它
答案 0 :(得分:0)
我们来看看DateTime.ToBinary Method和DateTime.Ticks Property文档。
首先, DateTime 的二进制形式表示两个属性(Kind和Ticks),并且不清楚它们是如何在二进制字符串中连接的。然后, Ticks 属性是自耶稣基督诞生以来 一百万分之一秒 的数量。
那么,如何进行?
尝试了解 Kind 和 Ticks 属性是如何二进制存储的。我们需要 Ticks 。我的建议是尝试将一些典型的DateTime值转换为二进制并分析输出。从 DateTime.MinValue 开始,该对应于01-01-0001 00:00:00
。您应该看到(我认为)全部为零,除了种类值(如果存在)。
获得64位 Ticks 值后,您可以使用floor($ticks / 10000000)
获得秒数。最后你必须减去从第1年到1970年经过的秒数(Unix标准),这是一个常数,你可以将C#DateTime 01-01-1970 00:00:00
转换成二进制......
答案 1 :(得分:0)
为此,您需要在C#中转换为unix时间戳,并将此数据打包为二进制而不是8字节的DateTime对象序列化。到2038年,4个字节就足够了。
从here借用(或窃取?),这是你在C#中创建Unix时间戳的方法:
public DateTime timestamp;
// ......
byte[] timestamp_bytes = new byte[8];
input.Read(timestamp_bytes, 0, 8);
timestamp = DateTime.FromBinary(System.BitConverter.ToInt64(timestamp_bytes, 0));
TimeSpan diff = (Timestamp - new DateTime(1970, 1, 1).toLocalTime());
int unix = (int) diff.TotalSeconds;
// unix is now a signed 32 bit integer representing the Unix timestamp in a way
// that PHP will understand
然后在PHP中,您可以将4个二进制字节转换回表示unix时间戳的整数,如下所示:
$timestamp = unpack('N', $binaryString);
echo date('d-m-Y H:i:s', $timestamp); // Should give 23-12-2011 09:54:56
答案 2 :(得分:0)
我最终得到了这个,解密后就解密了这个字符串。
$byte_array = array_slice(unpack("C*", "\0" . $decrypted), 1);
$timestamp_array = array_slice($byte_array, 0, 8);
$guid_array = array_slice($byte_array, 8, 16);
$is_read_only_array = array_slice($byte_array, 24, 1);
// CONVERT GUID
.....
// CONVERT TIMESTAMP
$timestamp_hex = "";
foreach ($timestamp_array as $byte) {
$timestamp_hex .= pack("C*", $byte);
}
$timestamp = hexdec($timestamp_hex);
// CONVERT IS READ ONLY
....