Python 中平方根的十六进制表示法 - Sha-512

发布于 2025-01-12 14:29:52 字数 805 浏览 3 评论 0原文

我正在回顾一下 Sha-512 的描述。提到初始哈希值由通过取前八个素数的小数部分获得的 64 位字序列组成。我试图在 Python 中复制这些值,但没有得到相同的结果。为了包含更多数字,我使用 mpmath 库。

from mpmath import *

mp.dps = 50

sqrt(2)
# mpf('1.4142135623730950488016887242096980785696718753769468')

mpf(0.4142135623730950488016887242096980785696718753769468 * 2 ** 64)
# mpf('7640891576956012544.0')

hex(7640891576956012544)
# '0x6a09e667f3bcc800'

但是,描述表明该值必须是6a09e667f3bcc908。可以看出,我得到的结果的最后三位数字与根据描述应该得到的结果不同。我想知道为什么会这样,正确的做法是什么。

我遇到过 类似的问题,但是将其调整为 64 位字会产生:

import math
hex(int(math.modf(math.sqrt(2))[0]*(1<<64)))
# '0x6a09e667f3bcd000'

这实际上在最后四个中有所不同数字。

I am going over the description of Sha-512. It is mentioned that the initial hash value consists of the sequence of 64-bit words that are obtained by taking the fractional part of the first eight primes. I am trying to replicate these values in Python, but I am not getting the same results. To include more digits, I am using the mpmath library.

from mpmath import *

mp.dps = 50

sqrt(2)
# mpf('1.4142135623730950488016887242096980785696718753769468')

mpf(0.4142135623730950488016887242096980785696718753769468 * 2 ** 64)
# mpf('7640891576956012544.0')

hex(7640891576956012544)
# '0x6a09e667f3bcc800'

However, the description indicates this value must be 6a09e667f3bcc908. As it can be seen, the result I get differs in the last three digits from what I should be getting according to the description. I was wondering why that is the case, and what is the correct approach.

I have come across a similar question, but adjusting it for 64-bit word would yield:

import math
hex(int(math.modf(math.sqrt(2))[0]*(1<<64)))
# '0x6a09e667f3bcd000'

which actually differs in the last four digits.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

↘紸啶 2025-01-19 14:29:52

正如评论已经解释的那样,您实际上在计算中只使用了 53 位(本机 CPython 浮点精度)。

这里有一个简单的方法来重现您显然想要的结果:

>>> import decimal
>>> x = decimal.getcontext().sqrt(2) - 1
>>> x
Decimal('0.414213562373095048801688724')
>>> hex(int(x * 2**64))
'0x6a09e667f3bcc908'

decimal 并没有什么真正神奇的地方。它只是碰巧默认使用足够的精度。您当然可以使用 mpmath 做同样的事情。

例如,

>>> import mpmath
>>> mpmath.mp.prec = 80
>>> hex(int(mpmath.frac( mpmath.sqrt(2) ) * 2**64))
'0x6a09e667f3bcc908'

As a comment already explained, you're actually only using 53 bits in your calculations (native CPython float precision).

Here's an easy way to reproduce the result you're apparently after:

>>> import decimal
>>> x = decimal.getcontext().sqrt(2) - 1
>>> x
Decimal('0.414213562373095048801688724')
>>> hex(int(x * 2**64))
'0x6a09e667f3bcc908'

Nothing really magical about decimal. It just happens to use enough precision by default. You could certainly do the same with mpmath.

For example,

>>> import mpmath
>>> mpmath.mp.prec = 80
>>> hex(int(mpmath.frac( mpmath.sqrt(2) ) * 2**64))
'0x6a09e667f3bcc908'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文