Python 中平方根的十六进制表示法 - Sha-512
Hexadecimal notation of square roots in Python - Sha-512
我正在检查 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
。可以看出,我得到的结果在最后三位与我根据描述应该得到的结果不同。我想知道为什么会这样,正确的方法是什么。
我遇到过 a similar question,但针对 64 位字调整它会产生:
import math
hex(int(math.modf(math.sqrt(2))[0]*(1<<64)))
# '0x6a09e667f3bcd000'
最后四位实际上不同。
正如已经解释过的评论,您实际上在计算中只使用了 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'
我正在检查 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
。可以看出,我得到的结果在最后三位与我根据描述应该得到的结果不同。我想知道为什么会这样,正确的方法是什么。
我遇到过 a similar question,但针对 64 位字调整它会产生:
import math
hex(int(math.modf(math.sqrt(2))[0]*(1<<64)))
# '0x6a09e667f3bcd000'
最后四位实际上不同。
正如已经解释过的评论,您实际上在计算中只使用了 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'