首页 > 解决方案 > 计算正弦的 MD5 整数部分时遇到问题

问题描述

我正在使用 MD5 实现,并使用 wikipedia 上的伪代码为整数正弦的二进制部分编写以下代码。我发现我的输出与广泛可用的预计算表之间存在差异。

我试图弄清楚我的代码是否不正确或维基百科上的伪代码不正确。在下面的代码中替换math.Floormath.Ceil修复了预计算表和我的输出之间的差异。

package main

import "fmt"
import "math"

func main() {
        var i float64
        for i < 64 {
                x := uint(math.Floor(float64(math.MaxUint32) * math.Abs(math.Sin(i+1))))
                fmt.Printf("%d : %x\n", uint(i+1), x)
                i = i + 1
        }
}
1 : d76aa477
2 : e8c7b755
3 : 242070db
4 : c1bdceee

第 1 行和第 2 行与预先计算的表不同,而第 3 行是一致的。

标签: gomd5

解决方案


问题是math.MaxUint32哪个是一个接一个!也就是说,2 32 -1 而不是 2 32

但无论如何,最简单/最快/常见/最好的选择是使用预先计算的表。

最终的 MD5 规范是RFC 1321

the integer part of 4294967296 times abs(sin(i)), where i is in radians.

其中“整数部分”应理解为底函数。当然,在适当的精度下floor(abs(sin)),它给出了 RFC 表中的数字。在这里,每个条目重新格式化为 8 个十六进制数字,并与Wolfram 的 Alpha吐出的内容进行了交叉检查BaseForm[Floor[Abs[2^32 Sin[Range[64]]]],16]

d76aa478 e8c7b756 242070db c1bdceee f57c0faf 4787c62a a8304613 fd469501 698098d8 8b44f7af ffff5bb1 895cd7be 6b901122 fd987193 a679438e 49b40821 f61e2562 c040b340 265e5a51 e9b6c7aa d62f105d 02441453 d8a1e681 e7d3fbc8 21e1cde6 c33707d6 f4d50d87 455a14ed a9e3e905 fcefa3f8 676f02d9 8d2a4c8a fffa3942 8771f681 6d9d6122 fde5380c a4beea44 4bdecfa9 f6bb4b60 bebfbc70 289b7ec6 eaa127fa d4ef3085 04881d05 d9d4d039 e6db99e5 1fa27cf8 c4ac5665 f4292244 432aff97 ab9423a7 fc93a039 655b59c3 8f0ccc92 ffeff47d 85845dd1 6fa87e4f fe2ce6e0 a3014314 4e0811a1 f7537e82 bd3af235 2ad7d2bb eb86d391 

推荐阅读