我在玩两种语言,决定比较一下计算速度。编写了一些几乎相同的程序来查找带有前导零的 sha-256 哈希。出于某种原因,python 出现得更快,在 2.8 秒内找到 5 个零,而 c# 在 6.8 中?计算散列的字符串以及由此产生的散列是相同的。我问这个问题是因为我看不出解释语言在这些计算中速度快 2.5 倍的逻辑,我对这个原因很感兴趣。我一个接一个地通过文件运行脚本.bat- 几乎同时。
以下是代码:
C#
using System;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Security.Cryptography;
namespace HelloWorld
{
class Hello {
static void Main(string[] args)
{
Stopwatch timer = new Stopwatch();
Console.WriteLine("Hello!");
int len = 0;
if (args.Length > 0 && args[0] != null)
{
len = Convert.ToInt32(args[0]);
}
else
{
Console.Write("Mask length: ");
len = Convert.ToInt32(Console.ReadLine());
}
string mask = "";
for (int i = 0; i < len; i++)
{
mask += "0";
}
Console.WriteLine("Mask: " + mask);
string str = "Num #";
string hash = "";
Console.WriteLine("Search...");
timer.Start();
for (int num = 0; true; num++)
{
hash = sha256(str + num);
if (hash.IndexOf(mask) == 0)
{
str = str + num;
break;
}
}
Console.WriteLine("Find!");
Console.WriteLine("Data: " + str);
Console.WriteLine("Hash: " + hash);
Console.WriteLine("Done: " + timer.Elapsed);
Console.ReadKey();
}
static string sha256(string randomString)
{
var crypt = new System.Security.Cryptography.SHA256Managed();
var hash = new System.Text.StringBuilder();
byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(randomString));
foreach (byte theByte in crypto)
{
hash.Append(theByte.ToString("x2"));
}
return hash.ToString();
}
}
}
Python
import sys
import time
import hashlib
def time_convert(sec):
mins = sec // 60
sec = sec % 60
hours = mins // 60
mins = mins % 60
return "{0}:{1}:{2}".format(int(hours),int(mins),sec)
print("Hello!");
if (len(sys.argv) > 1):
len = int(sys.argv[1]);
else:
len = int(input("Mask len: "));
mask = ""
for i in range(len):
mask += "0"
print("Mask: ", mask)
word = "Num #"
hash = ""
print("Search...")
start_time = time.time()
num = 0
while(True):
hash = hashlib.sha256((word + str(num)).encode()).hexdigest()
if hash.find(mask) == 0:
word = word + str(num)
break
num += 1
end_time = time.time()
time_lapsed = end_time - start_time
time_lapsed = time_convert(time_lapsed)
print("Find!");
print("Data: ", word);
print("Hash: ", hash);
print("Done: ", time_lapsed);
input()
无需深入优化。我在调试版本中运行您的代码。
我正在优化一点。
我正在运行调试版本。
我正在运行发布版本。
也就是说,粗略地说,它变得快了 10 倍。这不是优化的极限。
我不会厌倦说:这不是 C# 慢,而是用它写的代码那样。
瓶颈就在这条线上
hash.IndexOf(mask) == 0。字符串比较不是逐字节执行的,而是基于当前活动的区域性。为了使比较快速且逐字节地进行,有必要像这样hash.IndexOf(mask, StringComparison.Ordinal) == 0。好吧,或者正如我在上面的代码中所写的那样。将哈希类的创建移出循环会加快该过程,但效果并不显着。
Convert.ToHexString也纯粹是为了减少代码。为了好玩,我找了 6 个零。
我玩了一点黑魔法,也就是跨度,我在 10 秒内保持在 6 个零以内,但我不会展示它,因为它不适用于奇数个零,更准确地说,你需要完成它,这不符合问题的条件。也就是说,如果需要 8 位而不是 4 位的掩码精度,那么您通常可以很快做到。并且大致了解它的用途(可能是地穴) - 甚至更快。哦对了,我忘了,你也可以固定多线程。对于我的专业人士来说,它的速度是 x8 左右。