リバース エンジニアリングしようとしているチェックサムがあります。最初にチェックサムを作成するために使用された元の初期値を知っていれば、チェックサムを生成し続ける方法を既に知っています。
これまでのところ、ダブルデータ型の数式を使用してチェックサムが生成されることがわかっています。
計算されたチェックサムの最終値は符号なし整数ですが、その前に double から unsigned long long 別名 (unsigned __int64) に変換されます。
私がやろうとしているのは、元の初期値を取得するためにチェックサムを元に戻す次のステップに進むために、符号なし整数を double データ型の同じ値に戻すことです。
ここでチェックサムが計算されている間、double データ型で生成される値です。
3083570000.3115764
チェックサムを作成する0xB7CB8B50
これは損失の多い会話ではないと思うので、8 バイトの double から 4 バイトの整数チェックサムに変換しても実際には何も失われません。なんで?double
値は常に乗算によって作成されるため4294967295.0
、シフトのような末尾の 4 バイトを排除するだけだと私は信じています。
したがって、元の double 値を最後の桁に正確に戻すには、double
取得しようとしている値を で割る必要があります。4294967295.0
問題は、最後の小数点まで100%正確ではないため、適切に分割できないことです..浮動小数点演算では、IEEE浮動小数点のがらくたで100%正確ではないことを知っていますが、気にしません最初に作成されたのと同じ方法でこれを元に戻そうとしています。
出力
元のチェックサム double は0.71794958809146792
0.71794958809146792 * 4294967295.0 = 3083570000.3115761849416764
、パケットで送信された回答であるとします。0xb7cb8b50
符号なし整数0xb7cb8b50
をunsigned __int64
手動で手動でキャストすると、次のようになります0x00000000b7cb8b50
コードで生成された元の double は次のようになります。最初にチェックサムを作成するために同じ条件を再作成するために、パケットに追加される前に同じキーを使用しました。これは次のようになります。
Real ANSWER = 3083570000.3115764
そう
0x00000000b7cb8b50 should equals = 3083570000.3115764 double
私の逆コードは次のようになります
unsigned int checksum = 0xb7cb8b50;
double test1 = (double)(unsigned __int64)checksum;
double test2 = double(checksum);
double test3 = static_cast<double>(checksum);
double test4 = *((double*)(void*)&checksum);
上記のコードは、小数点以下数桁間違っています。
test1 returns = 3083570000.0000000
test2 returns = 3083570000.0000000
test3 returns = 3083570000.0000000
test4 returns = 1.523486003547e-314#DEN
どうすればエクストラを入手できますか、それ.3115764
も私の質問です。