forked from Qortal/qortal
Add threading to VanityGen
This commit is contained in:
parent
4330782bb7
commit
f7c6978151
@ -4,6 +4,8 @@ import java.io.IOException;
|
|||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
|
import org.bouncycastle.jsse.provider.BouncyCastleJsseProvider;
|
||||||
@ -16,37 +18,87 @@ import com.google.common.primitives.Bytes;
|
|||||||
|
|
||||||
public class VanityGen {
|
public class VanityGen {
|
||||||
|
|
||||||
|
// From utils.Base58:
|
||||||
|
private static final String ALPHABET_STR = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
private static String prefix = null;
|
||||||
|
|
||||||
|
private static void usage() {
|
||||||
|
System.err.println("Usage: Vanitygen [-t threads] <leading-chars>");
|
||||||
|
System.err.println("Example: VanityGen Qcat");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Generator implements Runnable {
|
||||||
|
public void run() {
|
||||||
|
Random random = new SecureRandom();
|
||||||
|
byte[] entropy = new byte[16];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
// Generate entropy internally
|
||||||
|
random.nextBytes(entropy);
|
||||||
|
|
||||||
|
// Use SHA256 to generate more bits
|
||||||
|
byte[] hash = Crypto.digest(entropy);
|
||||||
|
|
||||||
|
// Append first 4 bits from hash to end. (Actually 8 bits but we only use 4).
|
||||||
|
byte checksum = (byte) (hash[0] & 0xf0);
|
||||||
|
byte[] entropy132 = Bytes.concat(entropy, new byte[] { checksum });
|
||||||
|
|
||||||
|
String mnemonic = BIP39.encode(entropy132, "en");
|
||||||
|
|
||||||
|
PrivateKeyAccount account = new PrivateKeyAccount(null, hash);
|
||||||
|
|
||||||
|
if (!account.getAddress().startsWith(prefix))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
System.out.println(String.format("Address: %s, public key: %s, private key: %s, mnemonic: %s",
|
||||||
|
account.getAddress(), Base58.encode(account.getPublicKey()), Base58.encode(hash), mnemonic));
|
||||||
|
System.out.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String argv[]) throws IOException {
|
public static void main(String argv[]) throws IOException {
|
||||||
if (argv.length != 1) {
|
if (argv.length == 0)
|
||||||
System.err.println("Usage: Vanitygen <leading-chars>");
|
usage();
|
||||||
System.err.println("Example: VanityGen Qcat");
|
|
||||||
return;
|
int threadCount = 1;
|
||||||
|
|
||||||
|
int argIndex = 0;
|
||||||
|
while (argIndex < argv.length) {
|
||||||
|
String arg = argv[argIndex++];
|
||||||
|
|
||||||
|
if (arg.equals("-t")) {
|
||||||
|
if (argIndex >= argv.length)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
try {
|
||||||
|
threadCount = Integer.parseInt(argv[argIndex++]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prefix != null)
|
||||||
|
usage();
|
||||||
|
|
||||||
|
prefix = arg;
|
||||||
|
if (!prefix.matches("[" + ALPHABET_STR + "]+")) {
|
||||||
|
System.err.println("Only the following characters are allowed:\n" + ALPHABET_STR);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Security.insertProviderAt(new BouncyCastleProvider(), 0);
|
Security.insertProviderAt(new BouncyCastleProvider(), 0);
|
||||||
Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);
|
Security.insertProviderAt(new BouncyCastleJsseProvider(), 1);
|
||||||
|
|
||||||
Random random = new SecureRandom();
|
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
|
||||||
byte[] entropy = new byte[16];
|
|
||||||
|
|
||||||
while (true) {
|
for (int ti = 0; ti < threadCount; ++ti)
|
||||||
// Generate entropy internally
|
executor.execute(new Generator());
|
||||||
random.nextBytes(entropy);
|
|
||||||
|
|
||||||
// Use SHA256 to generate more bits
|
|
||||||
byte[] hash = Crypto.digest(entropy);
|
|
||||||
|
|
||||||
// Append first 4 bits from hash to end. (Actually 8 bits but we only use 4).
|
|
||||||
byte checksum = (byte) (hash[0] & 0xf0);
|
|
||||||
byte[] entropy132 = Bytes.concat(entropy, new byte[] { checksum });
|
|
||||||
|
|
||||||
String mnemonic = BIP39.encode(entropy132, "en");
|
|
||||||
|
|
||||||
PrivateKeyAccount account = new PrivateKeyAccount(null, hash);
|
|
||||||
|
|
||||||
if (account.getAddress().startsWith(argv[0]))
|
|
||||||
System.out.println(String.format("Address: %s, public key: %s, private key: %s, mnemonic: %s", account.getAddress(), Base58.encode(account.getPublicKey()), Base58.encode(hash), mnemonic));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user