Data update
This commit is contained in:
parent
29a5eea0d4
commit
5c1bb7bfa9
2011 changed files with 35081 additions and 3229 deletions
|
|
@ -0,0 +1,99 @@
|
|||
import java.math.BigInteger;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class BitcoinPublicPointToAddess {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String x = "50863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B2352";
|
||||
String y = "2CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6";
|
||||
|
||||
if ( areValidCoordinates(x, y) ) {
|
||||
System.out.println(encodeAddress(x, y));
|
||||
} else {
|
||||
System.out.println("Invalid Bitcoin public point coordinates");
|
||||
}
|
||||
}
|
||||
|
||||
// Return the encoded address of the given coordinates.
|
||||
private static String encodeAddress(String x, String y) {
|
||||
String publicPoint = BITCOIN_SPECIAL_VALUE + x + y;
|
||||
if ( publicPoint.length() != 130 ) {
|
||||
throw new AssertionError("Invalid public point string: " + publicPoint);
|
||||
}
|
||||
|
||||
byte[] messageBytes = computeMessageBytes(publicPoint);
|
||||
byte[] checksum = computeChecksum(messageBytes);
|
||||
messageBytes = Arrays.copyOf(messageBytes, messageBytes.length + 4);
|
||||
System.arraycopy(checksum, 0, messageBytes, 21, checksum.length);
|
||||
return encodeBase58(messageBytes);
|
||||
}
|
||||
|
||||
// Return the given byte array encoded into a base58 starting with most one '1'
|
||||
private static String encodeBase58(byte[] bytes) {
|
||||
final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
final int ALPHABET_SIZE = ALPHABET.length();
|
||||
|
||||
String[] temp = new String[34];
|
||||
for ( int n = temp.length - 1; n >= 0; n-- ) {
|
||||
int c = 0;
|
||||
for ( int i = 0; i < bytes.length; i++ ) {
|
||||
c = c * 256 + (int) ( bytes[i] & 0xFF );
|
||||
bytes[i] = (byte) ( c / ALPHABET_SIZE );
|
||||
c %= ALPHABET_SIZE;
|
||||
}
|
||||
temp[n] = ALPHABET.substring(c, c + 1);
|
||||
}
|
||||
|
||||
String result = Arrays.stream(temp).collect(Collectors.joining(""));
|
||||
while ( result.startsWith("11") ) {
|
||||
result = result.substring(1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return whether the given coordinates are those of a point on the secp256k1 elliptic curve
|
||||
private static boolean areValidCoordinates(String x, String y) {
|
||||
BigInteger modulus = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
|
||||
BigInteger X = new BigInteger(x, 16);
|
||||
BigInteger Y = new BigInteger(y, 16);
|
||||
return Y.multiply(Y).mod(modulus).equals(X.multiply(X).multiply(X).add(BigInteger.valueOf(7)).mod(modulus));
|
||||
}
|
||||
|
||||
private static byte[] computeMessageBytes(String text) {
|
||||
// Convert the hexadecimal string 'text' into a suitable ASCII string for the SHA256 hash
|
||||
byte[] bytesOne = hexToBytes(text);
|
||||
String asciiOne = new String(bytesOne, StandardCharsets.ISO_8859_1);
|
||||
String hexSHA256 = SHA256.messageDigest(asciiOne);
|
||||
// Convert the hexadecimal string 'hexSHA256' into a suitable ASCII string for the RIPEMD160 hash
|
||||
byte[] bytesTwo = hexToBytes(hexSHA256);
|
||||
String asciiTwo = new String(bytesTwo, StandardCharsets.ISO_8859_1);
|
||||
String hexRIPEMD160 = BITCOIN_VERSION_NUMBER + RIPEMD160.messageDigest(asciiTwo);
|
||||
return hexToBytes(hexRIPEMD160);
|
||||
}
|
||||
|
||||
private static byte[] computeChecksum(byte[] bytes) {
|
||||
// Convert the given byte array into a suitable ASCII string for the first SHA256 hash
|
||||
String asciiOne = new String(bytes, StandardCharsets.ISO_8859_1);
|
||||
String hexOne = SHA256.messageDigest(asciiOne);
|
||||
// Convert the hexadecimal string 'hex1' into a suitable ASCII string for the second SHA256 hash
|
||||
byte[] bytesOne = hexToBytes(hexOne);
|
||||
String asciiTwo = new String(bytesOne, StandardCharsets.ISO_8859_1);
|
||||
String hexTwo = SHA256.messageDigest(asciiTwo);
|
||||
return Arrays.copyOfRange(hexToBytes(hexTwo), 0, 4);
|
||||
}
|
||||
|
||||
private static byte[] hexToBytes(String text) {
|
||||
byte[] bytes = new byte[text.length() / 2];
|
||||
for ( int i = 0; i < text.length(); i += 2 ) {
|
||||
final int firstDigit = Character.digit(text.charAt(i), 16);
|
||||
final int secondDigit = Character.digit(text.charAt(i + 1), 16);
|
||||
bytes[i / 2] = (byte) ( ( firstDigit << 4 ) + secondDigit );;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private static final String BITCOIN_SPECIAL_VALUE = "04";
|
||||
private static final String BITCOIN_VERSION_NUMBER = "00";
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue