2

C#関数をPHPにコピーしています。C#では、GUID、DateTime、およびブール値がバイトに変換されます。次に、バイト配列がマージされてエンコードされます。最後のステップは、これをbase64に変換することです。

バイトの配列は、次の部分で構成されています。

GUID: 16 bytes
Timestamp: 8 bytes
Boolean: 1 byte

PHPでは、すでにbase64を変換し、文字列をバイトにデコードしました。また、最初の16バイトをGUIDに変換することもできました。PHPが返したバイトを検証しましたが、それらは正しいです。

現在、PHPで8バイトをタイムスタンプに変換しています。今のところ運がありません。問題は、int64を返すという事実だと思います。

C#

これは、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#の日時からバイト配列への変換です:

public DateTime Timestamp;
......
byte[] timestamp_bytes = System.BitConverter.GetBytes(Timestamp.ToBinary());

Timestamp.ToString()を出力すると、どちらの場合も23-12-201109:54:56になります。

PHP

PHPでは、8バイトの16進数を取得できました。

$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#アプリは私の権限下にないため、変更できることを保証できません

4

3 に答える 3

0

DateTime.ToBinaryメソッドDateTime.Ticksプロパティのドキュメントを見てみましょう。

まず、DateTimeのバイナリ形式は2つのプロパティ(KindとTicks)を表し、それらがバイナリ文字列でどのように連結されているかは明確ではありません。次に、Ticksプロパティは、イエス・キリストが生まれてから経過した1000万分の1秒の数です。

では、どのように進めますか?

  1. KindプロパティとTicksプロパティがどのようにバイナリに保存されるかを理解してください。ダニが必要です。私の提案は、いくつかの典型的なDateTime値をバイナリに変換し、出力を分析することです。DateTime.MinValueで開始します。これは、に対応する必要があり01-01-0001 00:00:00ます。Kind値(存在する場合)を除いて、すべてゼロが表示されるはずです(私は思います)。

  2. 64ビットのティック値を取得したら、を使用して秒を取得できますfloor($ticks / 10000000)。そして最後に、1年目から1970年(Unix標準)までに経過した秒数を引く必要があります。これは、C#DateTime01-01-1970 00:00:00をバイナリに変換して取得できる定数です...

幸運を。

于 2012-05-15T08:50:48.547 に答える
0

これを行うには、C#でUNIXタイムスタンプに変換し、このデータを8バイトのDateTimeオブジェクトのシリアル化ではなくバイナリにパックする必要があります。2038年までは、これには4バイトで十分です。

ここから借用(または盗む?)すると、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
于 2012-05-15T09:05:41.560 に答える
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
        ....
于 2013-08-04T17:17:02.547 に答える