RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1340341
Accepted
Daniil Screpchenko
Daniil Screpchenko
Asked:2022-03-21 00:57:13 +0000 UTC2022-03-21 00:57:13 +0000 UTC 2022-03-21 00:57:13 +0000 UTC

为什么在 python 中计算 sha-256 比在 c# 中更快?

  • 772

我在玩两种语言,决定比较一下计算速度。编写了一些几乎相同的程序来查找带有前导零的 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()
python
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    aepot
    2022-03-21T01:56:06Z2022-03-21T01:56:06Z

    无需深入优化。我在调试版本中运行您的代码。

    Hello!
    Mask length: 5
    Mask: 00000
    Search...
    Find!
    Data: Num #646714
    Hash: 00000b4eecf7c2687378eb776f9d7e02f4ee4d46883ec750fdd2e238702ee386
    Done: 00:00:09.9405143
    

    我正在优化一点。

    static void Main(string[] args)
    {
        Stopwatch timer = new Stopwatch();
    
        Console.WriteLine("Hello!");
    
        int len;
        if (args.Length > 0 && args[0] != null)
        {
            len = int.Parse(args[0]);
        }
        else
        {
            Console.Write("Mask length: ");
    
            len = int.Parse(Console.ReadLine());
        }
    
        string mask = new string('0', len);
    
        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.StartsWith(mask, StringComparison.Ordinal))
            {
                str += num;
                break;
            }
        }
    
        timer.Stop();
    
        Console.WriteLine("Find!");
        Console.WriteLine("Data: " + str);
        Console.WriteLine("Hash: " + hash.ToLower());
        Console.WriteLine("Done: " + timer.Elapsed);
    
        Console.ReadKey();
    }
    
    static SHA256Managed crypt = new SHA256Managed();
    static string sha256(string randomString)
    {
        byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(randomString));
        return Convert.ToHexString(crypto);
    }
    

    我正在运行调试版本。

    Hello!
    Mask length: 5
    Mask: 00000
    Search...
    Find!
    Data: Num #646714
    Hash: 00000b4eecf7c2687378eb776f9d7e02f4ee4d46883ec750fdd2e238702ee386
    Done: 00:00:00.8002694
    

    我正在运行发布版本。

    Hello!
    Mask length: 5
    Mask: 00000
    Search...
    Find!
    Data: Num #646714
    Hash: 00000b4eecf7c2687378eb776f9d7e02f4ee4d46883ec750fdd2e238702ee386
    Done: 00:00:00.5345979
    

    也就是说,粗略地说,它变得快了 10 倍。这不是优化的极限。

    我不会厌倦说:这不是 C# 慢,而是用它写的代码那样。

    瓶颈就在这条线上hash.IndexOf(mask) == 0。字符串比较不是逐字节执行的,而是基于当前活动的区域性。为了使比较快速且逐字节地进行,有必要像这样hash.IndexOf(mask, StringComparison.Ordinal) == 0。好吧,或者正如我在上面的代码中所写的那样。

    将哈希类的创建移出循环会加快该过程,但效果并不显着。Convert.ToHexString也纯粹是为了减少代码。

    为了好玩,我找了 6 个零。

    Hello!
    Mask length: 6
    Mask: 000000
    Search...
    Find!
    Data: Num #31184147
    Hash: 000000de3652ae021f32fc4cb4b6fda5807ed3b0fbea4641841a8078b5e4f668
    Done: 00:00:24.4929515
    

    我玩了一点黑魔法,也就是跨度,我在 10 秒内保持在 6 个零以内,但我不会展示它,因为它不适用于奇数个零,更准确地说,你需要完成它,这不符合问题的条件。也就是说,如果需要 8 位而不是 4 位的掩码精度,那么您通常可以很快做到。并且大致了解它的用途(可能是地穴) - 甚至更快。哦对了,我忘了,你也可以固定多线程。对于我的专业人士来说,它的速度是 x8 左右。

    • 5

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5