1

我目前正在编写一种快速的自定义编码方法,在该方法中我用数字标记一个键,以验证它是一个有效的键。

基本上,我从编码中取出任何数字并将其乘以一个键。

然后,我会将这些数字乘以部署到购买密钥的用户/客户。我想简单地使用 (Code % Key == 0) 来验证密钥是否有效,但对于较大的值,mod 函数似乎无法按预期运行。

号码 = 468721387;密钥 = 12345678;代码=数字*键;

使用上面的数字:代码 % 键 == 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 。

一个简单的解决方案就是在您的代码中将“long”更改为“decimal”(或“double”)。

在 .NET 4.0 中,有一个新的BigInteger类。

最后,您说您“……编写一个快速的自定义编码方法……”,所以一个简单的自制解决方案可能会满足您的需求。但是,如果这是生产代码,您可能会考虑更强大的解决方案,包括密码学或专门从事软件许可的第三方提供的解决方案。

于 2009-10-12T21:50:04.293 回答
5

说整数溢出可能是罪魁祸首的答案几乎肯定是正确的;您可以通过在乘法周围放置一个“已检查”块并查看它是否引发异常来验证这一点。

但这里还有一个更大的问题,似乎每个人都忽略了。

最好的办法是退后一步,重新考虑整个计划的智慧。您似乎正在尝试设计一个基于密码的安全系统,但您显然不是密码算法方面的专家。这是一个巨大的红色警告标志。如果您需要基于加密的安全系统,请不要尝试自己动手。有很多现成的加密系统由专家构建,经过大量测试并且随时可用。使用其中之一。

如果您实际上一心想要推出自己的加密货币,那么在 64 位中正确计算是您最不担心的事情。64 位整数对于这个加密应用程序来说太小了。您需要使用更大的整数大小;否则,找到与代码匹配的密钥是微不足道的。

再次强调,构建正确的基于加密的安全代码实际上保护真实用户免受真正威胁是多么困难。

于 2009-10-12T22:12:48.737 回答
4

整数溢出...请参阅我的评论。

您正在执行的乘法值会溢出int数据类型并导致其换行(int值介于 +/-2147483647 之间)。

选择一个更合适的数据类型来保存一个大到 5786683315615386 的值(乘法的结果)。

更新

您的新示例稍微改变了一些事情。

您使用的是 long,但现在您使用的是 System.DateTime.Ticks,它在 Mono(不确定 MS 平台)上返回 633909674610619350。

当你将它乘以一个大数时,你现在溢出 along就像你之前溢出 an 一样int。那时,您可能需要使用 adouble来处理您想要的值(decimal可能也有效,具体取决于您的乘数有多大)。

于 2009-10-12T21:04:40.630 回答
2

显然,您Code不适合int数据类型。尝试long改用:

long code = (long)number * key;

(long)演员阵容是必要的。如果没有强制转换,则乘法将以 32 位整数形式完成(假设变量是类型化number的),结果将被强制转换为您不想要的结果。通过将操作数之一转换为,您可以告诉编译器对两个数字执行乘法运算。keyintlonglonglong

于 2009-10-12T21:02:03.003 回答