zoukankan      html  css  js  c++  java
  • 比特币挖矿算法简化模拟及耗时估算

    简化模拟

    0.假设挖矿难度为整数d(d>0)
    1.随机生成一个整数x
    2.对整数x进行摘要计算hash(x),得到s,即s=hash(x)
    3.对s前导字符串判定:如为d个'0',则矿已挖到,结束;否则跳到步骤1.

    一句话:不断随机生成整数,直到对生成的整数被进行摘要计算得到的字符串以某个数目的0开头为止。

    摘要算法选用sha256

    代码实现:

     1 package cn.ubingo.block_chain;
     2 
     3 import java.util.Collections;
     4 import java.util.Date;
     5 import java.util.Random;
     6 
     7 public class Demo {
     8     static Random r = new Random();
     9 
    10     public static void main(String[] args) {
    11 
    12         int dificulty = 3;
    13         String zeros = String.join("", Collections.nCopies(dificulty, "0"));
    14         System.out.println(zeros);
    15 
    16         Date start = new Date();
    17         long times = 0;
    18         while (true) {
    19             String sha = Sha.getSHA256StrJava(r.nextInt() + "");
    20             // System.out.println(sha);
    21             times++;
    22             if (sha.startsWith(zeros))
    23                 break;
    24         }
    25         Date end = new Date();
    26         long use = end.getTime() - start.getTime();
    27 
    28         System.out.println(times + " in " + use + "ms with dificulty " + dificulty);
    29     }
    30 
    31 }

    输出结果:

    000

    4973 in 106ms with dificulty 3

    耗时计算

    让难度从1递增,每个难度挖10次矿,取耗时最久的那次作为参考。

    package cn.ubingo.block_chain;
    
    import java.util.Collections;
    import java.util.Date;
    import java.util.Random;
    
    public class App {
        static Random r = new Random();
    
        public static void main(String[] args) {
    
            int dificulty = 0;
    
            while (true) {
                dificulty++;
                String zeros = String.join("", Collections.nCopies(dificulty, "0"));
                System.out.println(zeros);
                long maxUse = 0;
                long maxTimes = 0;
                for (int i = 0; i < 10; i++) {
                    Date start = new Date();
                    long times = 0;
                    while (true) {
                        String sha = Sha.getSHA256StrJava(r.nextInt() + "");
                        //System.out.println(sha);
                        times++;
                        if (sha.startsWith(zeros))
                            break;
                    }
                    Date end = new Date();
                    long use = end.getTime() - start.getTime();
                    if (use > maxUse) {
                        maxUse = use;
                        maxTimes = times;
                    }
                }
                System.out.println(maxTimes + " in " + maxUse + "ms with dificulty " + dificulty);
            }
    
        }
    }

    输出结果(代码还在跑):

    0
    19 in 32ms with dificulty 1
    00
    366 in 11ms with dificulty 2
    000
    11377 in 73ms with dificulty 3
    0000
    153888 in 377ms with dificulty 4
    00000
    3160837 in 4568ms with dificulty 5
    000000
    55559940 in 81454ms with dificulty 6
    0000000
    637485941 in 977748ms with dificulty 7
    00000000
    8540898666 in 12283075ms with dificulty 8
    000000000

    ===========================================================

    从上面结果可以看出,当难度为8时,一个人挖,耗时204分钟(12283075ms)左右。

    由于挖矿算法具有的随机性,如要求在10分钟内挖到矿,需要204/10=20个同等算力的矿工同时挖。

    如果难度为72(比特币当前的难度),可想而知需要的矿工数量得是什么级别。

    由于挖矿算法具有的随机性,谁的算力强,谁的矿工多,谁挖到矿的几率就大,谁就能发大财。(所以矿机和矿场登场了)

    ===========================================================

    代码中用到的工具类如下(网上找的)

    package cn.ubingo.block_chain;
    
    import java.io.UnsupportedEncodingException;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    public class Sha {
    
        /**
         *  利用java原生的摘要实现SHA256摘要计算
         * @param content 原文
         * @return
         */
        public static String getSHA256StrJava(String content){
            MessageDigest messageDigest;
            String encodeStr = "";
            try {
                messageDigest = MessageDigest.getInstance("SHA-256");
                messageDigest.update(content.getBytes("UTF-8"));
                encodeStr = byte2Hex(messageDigest.digest());
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return encodeStr;
        }
    
        /**
         * 将byte转为16进制
         * @param bytes
         * @return
         */
        private static String byte2Hex(byte[] bytes){
            StringBuffer stringBuffer = new StringBuffer();
            String temp = null;
            for (int i=0;i<bytes.length;i++){
                temp = Integer.toHexString(bytes[i] & 0xFF);
                if (temp.length()==1){
                    //1得到一位的进行补0操作
                    stringBuffer.append("0");
                }
                stringBuffer.append(temp);
            }
            return stringBuffer.toString();
        }
        
    }
  • 相关阅读:
    CSRF的防御解决过程
    Spring生态研习【三】:Spring-kafka
    Spring生态研习【二】:SpEL(Spring Expression Language)
    Spring生态研习【一】:定时任务Spring-task
    给定一个大的任务,需要在考虑性能的情况下,快速处理完,并报告结果
    给定一个大于2的偶数,将其分解为两个质数的和
    一个求解平方根的算法题
    Kafka研究【一】:bring up环境
    LB+nginx+tomcat7集群模式下的https请求重定向(redirect)后变成http的解决方案
    IDEA使用笔记(八)——自动生成 serialVersionUID 的设置
  • 原文地址:https://www.cnblogs.com/FoChen/p/9516075.html
Copyright © 2011-2022 走看看