愚公哈希!我竟然真的穷举验证了一下,用我的计算机CPU(iMac 5K 2019: i5-9600K,稍老) 需要:
注意,单位是“亿亿亿年”,才能完成穷举比较:
所以,我还没有得出答案,请稍等。
在iMac上面我的6核6线程跑满,是需要 0.904 亿亿亿年,i5-9600K
但是在另外一台 6核12线程跑满,却需要 1.15 亿亿亿年,i7-10850H
玛德,这有点让我Windows粉转路人的感jiǒ,这还是新一代的i7啊,牙膏特尔!
我目前的答案是:
没有这样的字符串。
我已经算了半小时,等我80岁的时候我再来更新这个答案(弱弱的问一下,停电了我要重新计算吗?在线等,挺急的。。。),正在写稿:
我的是2019年的9600K,如果谁有下面两款CPU,11600K或者12600K的,如果也能跑一下这个hash测试,看看1)拼接32个字符,然后2)做一次MD5 hash,然后3)比较一次他俩是否==相等,做2^27个,看看需要多少秒,我的是53秒,让我看看你们的是多少,看一下牙膏特尔这两年到底挤了多少;i9的兄弟们就低调些啊,不要来伤害我这种i5咖位的了吧。
sysctl machdep.cpu machdep.cpu.brand_string: Intel(R) Core(TM) i5-9600K CPU @ 3.70GHz
时间计算:
# 亿亿亿年 # 16^32 / 2^27 = 2^101; # 2^27 比较需要 53秒; pow(2,101)*53/(3600*24*365)/(100000000**3) 4.260875305181136
我用golang穷举,先统计了计算 2^27 个(134217728)md5(str1)==str1,需要 53 秒
0 : 00000000000000000000000000000000 : Duration: 0 . 134217728 : 00000000000000000000000008000000 : Duration: 53 . 268435456 : 00000000000000000000000010000000 : Duration: 107 . 402653184 : 00000000000000000000000018000000 : Duration: 161 . 536870912 : 00000000000000000000000020000000 : Duration: 217 .
主要步骤如下:
单核: 4.26 亿亿亿年 的最简单写法:
if M == GetMD5(M) { fmt.Println(M, ":", GetMD5(M)) } if Letter_counter%134217728 == 0 { PrintDurationSeconds(M) } if Letter_counter == math.MaxInt64-1 { Letter_counter = 0 } Letter_counter++
当我用6核来算的时候,每分钟 715979273 次,约为 1200万 次比较每秒:
总共需要:
harry$ ./main_c6 119346194 :G01: 60 119356506 :G23: 60 119296085 :G45: 60 119322962 :G67: 60 119292723 :G89: 60 119364401 :GAB: 60 0 :GCD: 60 0 :GEF: 60 TOTALLY in 60 seconds: 715979273 // 六核心每分钟性能 harry$ ./main_c8 89537305 :G01: 60 88989713 :G23: 60 88977012 :G45: 60 88566971 :G67: 60 88641961 :G89: 60 88777951 :GAB: 60 88326244 :GCD: 60 90716045 :GEF: 60 TOTALLY in 60 seconds: 712533437 // 八核心,因为我没有8核心,在6核心上面当8核心跑,还不如6核心的,符合预期; // 那么 如果把程序改成 分为16组,在至强或者锐龙9上面跑,性能是可以成线性提升的,只要不超过核心数就行;
在小新锐龙的6核上面表现也很好,但是因为是轻薄本,前面2分钟还行,3分钟以后就下降了,不如最开始的两分钟,应该是散热跟不上导致的。iMac的6核成绩是稳定保存10分钟都没用问题的。
测试代码:
// 加上 LockOSThread, 可以每分钟多跑13万次hash runtime.LockOSThread() numCPU := runtime.NumCPU() // 目前最多一次跑16个线程; // 在超过16线程(物理8核心16线程或者16核心)的机器上,因为会发生CPU切换,还不如在16核心机器上 wg := sync.WaitGroup{} wg.Add(numCPU + 1) go func() { // 每 60 秒打印一次 8个计数器,并求和 }() if numCPU > 0 { go func() { SearchMD5_0() }() } if numCPU > 1 { go func() { SearchMD5_1() }() } if numCPU > 2 { go func() { SearchMD5_2() }() } // 省略 if numCPU > 14 { go func() { SearchMD5_e() }() } if numCPU > 15 { go func() { SearchMD5_f() }() } wg.Wait()