如何计算密码学中的对数?
我正在尝试对字节执行非线性函数来实现 SAFER+。该算法需要计算字节的以 45 为底的对数,我不明白如何做到这一点。
log45(201) = 1.39316393
当我将其分配给一个字节时,该值被截断为 1,并且我无法恢复确切的结果。
我该怎么处理这个事情?
I am trying to perform non-linear functions on bytes to implement SAFER+. The algorithm requires computing base-45 logarithm on bytes, and I don't understand how to do it.
log45(201) = 1.39316393
When I assign this to a byte, the value is truncated to 1, and I can't recover the exact result.
How am I supposed to handle this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
密码学经常使用 素数域,在本例中为 GF(257)。 <一href="http://books.google.com/books?id=_g-fDjmi1xAC&pg=PA60&lpg=PA60&dq=field%2045%20257%20safer%2b&source=bl&ots=pxx5Qxhvx3& ;sig=Js7MaBkdiyeLdCOeMXBcAIsXVUU&hl=en&ei=yyvZTrX5A5TciQL1uPC7Bg&sa=X&oi=book_result&ct=结果&resnum=1&ved=0CBwQ6AEwAA" rel="nofollow">创建一个指数表,如下所示:
“log”值为 45exp % 257。您需要一个带有
modPow
函数(将数字求幂,对某个值取模)来构建此表。您可以看到“exp”128 的值是一种特殊情况,因为通常零的对数是未定义的。通过在“log”列中查找数字来计算该数字的对数;该行“exp”列中的值是对数。
以下是初始化的草图:
例如,使用此设置,log45(131) =
log[131]
= 63 和 4538 =exp[38]
= 59。(我从未编写过 C#;我只是从
BigInteger
文档可能有;数据类型错误。)Cryptography often uses prime fields, in this case, GF(257). Create an exponentiation table that looks like this:
The "log" values are 45exp % 257. You'll need an arbitrary precision arithmetic library with a
modPow
function (raise a number to a power, modulo some value) to build this table. You can see that the value for "exp" 128 is a special case, since normally the logarithm of zero is undefined.Compute the logarithm of a number by finding the it in the "log" column; the value in the "exp" column of that row is the logarithm.
Here's a sketch of the initialization:
With this setup, for example, log45(131) =
log[131]
= 63, and 4538 =exp[38]
= 59.(I've never written C#; I'm just guessing from the
BigInteger
documentation; there are likely to be errors with the data types.)那么您有一个字节值(从 0 到 255),并且想要获取以 45 为底的对数,并将其存储在另一个字节中?正如其他人所说,这样做会失去一些准确性。但是,您可以做得比仅仅将
double
结果转换为byte
更好。255 的对数以 45 为底约为 1.455675。您可以通过将其乘以一个常数因子来将其存储在一个字节中,但准确性会有所损失。什么常数因子?您可以使用 100,这将为您提供 145 的值,但您会丢失几乎一半的字节范围。由于您要表示的最大值是 1.455675,因此您可以使用常数乘数
255/log45(255)
,即 175.176 左右。这效果如何?让我们看看...
在我的计算机上的 .NET 4 下,最大错误为 2.1419%,平均错误为 1.0501%。
您可以通过对
Math.Pow
的结果进行四舍五入来减少平均误差。即:将平均误差降低至 0.9300%,但将最大误差增大至 3.8462%。
So you have a byte value (from 0 to 255), and you want to get the log base 45, and store it in another byte? As others have said, you're going to lose some accuracy in doing that. However, you can do better than just casting the
double
result to abyte
.The log base 45 of 255 is approximately 1.455675. You can store that in a byte, with some loss of accuracy, by multiplying it by a constant factor. What constant factor? You could use 100, which would give you a value of 145, but you're losing almost half the range of a byte. Since the largest value you want to represent is 1.455675, you can use a constant multiplier of
255/log45(255)
, or about 175.176.How well does this work? Let's see ...
Under .NET 4 on my machine, that gives me a maximum error of 2.1419%, and an average error of 1.0501%.
You can reduce the average error by rounding the result from
Math.Pow
. That is:That reduces the average error to 0.9300%, but increases the maximum error to 3.8462%.
向我们展示代码可能会有所帮助,但我怀疑您的问题来自于存储结果。
如果您想存储非整数,您不想将其放入字节中,因为这会截断它(如您所见)。相反,将结果存储为双精度或更合适的形式:
我应该补充一点,我不确定 SAFER+ 是什么,所以这个答案可能没有帮助,但希望它能为您指明正确的方向。
Showing us the code might help but I suspect your problem comes from storing the result.
If you want to store a non-integer number you don't want to put it into a byte since that will truncate it (as you are seeing). Instead store the result in a double or something more appropriate:
I should add that I'm not sure what SAFER+ is so this answer may not be helpful but hopefully it should point you in the right direction.
这并不是真正的答案,但查看此问题的一小部分用户可能会对
double
类型到byte[]
类型的转换感兴趣。可以做的很简单:
这
使用了我相信.NET 中最初存在的
BitConverter
类。This is not really an answer, but a fraction of the users viewing this question will probably be interrested in the conversion of a
double
type to abyte[]
type.What could be done is simply:
and
this uses the
BitConverter
class which I believe exists in .NET initialy.