1

私は現在、それが有効なキーであることを確認するために数字でキーをスタンプする簡単なカスタム エンコーディング メソッドを書いています。

基本的に、エンコーディングから出てくる数字をキーで乗算していました。

次に、これらの数値を乗算して、キーを購入したユーザー/顧客に展開します。(Code % Key == 0) を使用してキーが有効であることを確認したかったのですが、値が大きい場合、mod 関数は期待どおりに機能していないようです。

番号 = 468721387; キー = 12345678; コード = 番号 * キー;

上記の数値を使用: Code % Key == 11418772

小さい数値の場合は正しく 0 を返します。.NET で long の割り切れる可能性を確認する信頼できる方法はありますか?

ありがとう!

編集:わかりました、私が特別で、何かが足りないかどうか教えてください...

        long a = DateTime.Now.Ticks;
        long b = 12345;
        long c = a * b;
        long d = c % b;
        d == 10001 (Bad)

        long a = DateTime.Now.Ticks;
        long b = 12;
        long c = a * b;
        long d = c % b;
        d == 0 (Good)

私は何を間違っていますか?

4

4 に答える 4

6

他の人が言っているように、あなたの問題は整数のオーバーフローです。[ビルドの詳細設定]ダイアログで[算術オーバーフロー/アンダーフローの確認]をオンにすると、これをより明確にすることができます。これを行うと、* DateTime.Now.Ticks *12345*を実行したときにOverflowExceptionが発生します。

簡単な解決策の1つは、コード内で「long」を「decimal」(または「double」)に変更することです。

.NET 4.0には、新しいBigIntegerクラスがあります。

最後に、あなたは「...簡単なカスタムエンコーディングメソッドを書いている...」と言っているので、単純な自作ソリューションで十分かもしれません。ただし、これが実稼働コードである場合は、暗号化またはソフトウェアライセンスを専門とするサードパーティの何かを含むより堅牢なソリューションを検討することをお勧めします。

于 2009-10-12T21:50:04.293 に答える
5

整数オーバーフローが原因である可能性が高いという答えは、ほぼ確実に正しいです。乗算の周りに「チェック済み」ブロックを配置し、例外がスローされるかどうかを確認することで、それを確認できます。

しかし、ここには、誰もが無視しているように見える、はるかに大きな問題があります。

最善の方法は、大きく一歩下がって、このスキーム全体の知恵を再考することです。あなたは暗号ベースのセキュリティ システムを設計しようとしているようですが、明らかに暗号演算の専門家ではありません。それは巨大な赤い警告フラグです。暗号ベースのセキュリティ システムが必要な場合は、自分で巻こうとしないでください。専門家によって構築され、十分にテストされ、すぐに利用できる既製の暗号システムがたくさんあります。それらの1つを使用してください。

実際に自分の仮想通貨を転がすことに夢中になっている場合、64 ビットで計算を正しく行うことは、ほとんど心配する必要がありません。64 ビット整数は、この暗号化アプリケーションには小さすぎます。はるかに大きな整数サイズを使用する必要があります。それ以外の場合、コードに一致するキーを見つけるのは簡単です。

繰り返しますが、実際のユーザーを実際の脅威から実際に保護する正しい暗号ベースのセキュリティ コードを構築することがいかに難しいかを強調しきれません。

于 2009-10-12T22:12:48.737 に答える
4

整数オーバーフロー...私のコメントを参照してください。

実行している乗算の値は、データ型をオーバーフローさせint、ラップします (int値は +/-2147483647 の間に収まります)。

より適切なデータ型を選択して、5786683315615386 (乗算の結果) までの値を保持します。

アップデート

あなたの新しい例は物事を少し変えます。

long を使用していますが、現在は System.DateTime.Ticks を使用しており、Mono (MS プラットフォームについては不明) で 633909674610619350 を返しています。

これに大きな数を掛けると、以前にオーバーフローしていたのlongと同じように、オーバーフローしてintいます。その時点で、おそらく a を使用して、必要なdouble値を操作する必要がありdecimalます (乗数の大きさによっては、同様に機能する場合もあります)。

于 2009-10-12T21:04:40.630 に答える
2

どうやら、データ型Codeに収まらないようです。代わりにint使用してみてください:long

long code = (long)number * key;

(long)キャストは必要です。キャストを使用しないと、乗算は 32 ビット整数形式で行われ (numberkey変数が typedであると仮定int)、結果がキャストされますが、これは目的longとは異なります。オペランドの 1 つを にキャストすることによりlong、2 つの数値で乗算を実行するようにコンパイラに指示しlongます。

于 2009-10-12T21:02:03.003 に答える