比特币区块头 - 双 SHA256 不起作用



我有以下java代码:

public class DoubleSHA256 {
    final protected static char[] hexArray = "0123456789abcdef".toCharArray();
    public static String gen(String input) {
        MessageDigest digester = null;
        try {
            digester = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return bytesToHex(digester.digest(digester.digest(input.getBytes())));
    }
    private static String bytesToHex(final byte[] bytes)
    {
        char[] hexChars = new char[bytes.length * 2];
        for ( int j = 0; j < bytes.length; j++ ) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }
}

类的调用如下:

System.out.println(DoubleSHA256.gen(
    "0100000081cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122bc7f5d74df2b9441a42a14695"
));

结果是:

6500f13bc254c59e9f3d77bd0b1999e686fadf7765ae2b59266d1d835b869083

,但应该是:

1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e0000000000000000

00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d

来源(https://en.bitcoin.it/wiki/Block_hashing_algorithm):

>>> import hashlib
>>> header_hex = ("01000000" +
    "81cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000" +
    "e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122b" +
    "c7f5d74d" +
    "f2b9441a" +
    "42a14695")
>>> header_bin = header_hex.decode('hex')
>>> hash = hashlib.sha256(hashlib.sha256(header_bin).digest()).digest()
>>> hash.encode('hex_codec')
'1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e0000000000000000'
>>> hash[::-1].encode('hex_codec')
'00000000000000001e8d6829a8a21adc5d38d0a473b144b6765798e61f98bd1d'

谁能给我一个提示是怎么回事?

加密哈希返回字节,而不是十六进制。十六进制只是一种使输出可读的方法。因此,您首先需要解码十六进制输入,然后编码输出-如果需要十六进制的值,即。然而,双哈希本身在编码/解码中应该是无效的。

得到:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.bouncycastle.util.encoders.Hex;
public class DoubleSHA256 {
    final protected static char[] hexArray = "0123456789abcdef".toCharArray();
    public static byte[] gen(byte[] input) {
        MessageDigest digester = null;
        try {
            digester = MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return digester.digest(digester.digest(input));
    }
    private static String bytesToHex(final byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }
    public static void main(String[] args) {
        System.out.println(bytesToHex(gen(Hex.decode("0100000081cd02ab7e569e8bcd9317e2fe99f2de44d49ab2b8851ba4a308000000000000e320b6c2fffc8d750423db8b1eb942ae710e951ed797f7affc8892b0f1fc122bc7f5d74df2b9441a42a14695"))));
    }
}
输出:

1dbd981fe6985776b644b173a4d0385ddc1aa2a829688d1e0000000000000000
我将把它留给你来实现十六进制解码器和字节数组的反转。或者你可以使用任何可用的在线编码器,如Apache Commons Codec, Bouncy Castle, Guava等。

最新更新