/* * * Copyright 2014 http://Bither.net * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * / */ package net.bither.utils; import net.bither.BitherSetting; import net.bither.bitherj.utils.Utils; import net.bither.model.OpenCLDevice; import net.bither.platform.builder.OSUtils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class BitherVanitygen { private enum OUT_TYEP { OUT, ERROR; } public interface IVanitygenListener { public void onProgress(String speed, long generated, double progress, int nextPossibility, String nextTimePeriodSeconds); public void getAddress(String address); public void getPrivateKey(String privateKey, long useTime); public void onDifficulty(String difficile); public void error(String error); } private static final String ADDRESS_FORMAT = "Address: "; private static final String PRIVATE_FORMAT = "Privkey: "; private static final String PROGRESS_FORMAT = "\\[(.*)\\]\\[total (\\d+)\\]\\[Prob (\\d+\\.\\d+)%\\]\\[(\\d+)% in (.*)\\]"; private static final String DIFFICULTY_FORMAT = "Difficulty: "; private static final String AVAILABLE_OPENCL_FORMAT = "\\d+:\\s*\\[.*\\]"; private static final String MAC_LINUX_VANITYGEN = "vanitygen"; private static final String MAC_LINUX_OCLVANITYGEN = "oclvanitygen"; private static final String WINDOWS_VANITYGEN = "vanitygen.exe"; private static final String WINDOWS_VANITYGEN_64 = "vanitygen64.exe"; private static final String WINDOWS_OCLVANITYGEN = "oclvanitygen.exe"; private static final String WINDOWS_OCLVANITYGEN_64 = "oclvanitygen64.exe"; private static final String WINDOWS_PATH = "/vanitygen/windows/"; private static final String MAC_OS_PATH = "/vanitygen/mac/"; private static final String LINUX_PATH = "/vanitygen/linux/"; private String input; private String openclConfig; private boolean useOpencl; private boolean igoreCase; private Process process = null; private IVanitygenListener vanitygenListener; private boolean generatedKey = false; private long beginTime; private int threadNum; private BitherSetting.ECKeyType ecKeyType; public BitherVanitygen(String input, boolean useOpencl, boolean igoreCase, int threadNum , BitherSetting.ECKeyType ecKeyType, String openclConfig, IVanitygenListener vanitygenListener) { this.input = input; this.useOpencl = useOpencl; this.igoreCase = igoreCase; this.threadNum = threadNum; this.ecKeyType = ecKeyType; this.openclConfig = openclConfig; this.vanitygenListener = vanitygenListener; } public void generateAddress() { beginTime = System.currentTimeMillis(); String path = ""; if (OSUtils.isMac()) { path = getFilePath(MAC_OS_PATH + MAC_LINUX_VANITYGEN); if (useOpencl) { path = getFilePath(MAC_OS_PATH + MAC_LINUX_OCLVANITYGEN); } } else if (OSUtils.isLinux()) { path = getFilePath(LINUX_PATH + MAC_LINUX_VANITYGEN); if (useOpencl) { path = getFilePath(LINUX_PATH + MAC_LINUX_OCLVANITYGEN); } } else if (OSUtils.isWindows()) { if (SystemUtil.isSystem32()) { path = getFilePath(WINDOWS_PATH + WINDOWS_VANITYGEN); System.out.println("system 32"); } else { System.out.println("system 64"); path = getFilePath(WINDOWS_PATH + WINDOWS_VANITYGEN_64); } if (useOpencl) { if (SystemUtil.isSystem32()) { path = getFilePath(WINDOWS_PATH + WINDOWS_OCLVANITYGEN); } else { path = getFilePath(WINDOWS_PATH + WINDOWS_OCLVANITYGEN_64); } } } if (Utils.isEmpty(path)) { if (this.vanitygenListener != null) { this.vanitygenListener.error("vanitygen not exist"); } return; } List<String> params = new ArrayList<String>(); params.add(path); if (igoreCase) { params.add("-i"); } if (useOpencl) { params.add("-D " + openclConfig); } if (!useOpencl) { if (threadNum > 0 && threadNum <= SystemUtil.getAvailableProcessors()) { params.add("-t " + threadNum); } } if (!OSUtils.isWindows() || !SystemUtil.isSystem32()) { if (ecKeyType == BitherSetting.ECKeyType.UNCompressed) { params.add("-F" + "uncompressed"); } } params.add(input); String[] array = new String[params.size()]; array = params.toArray(array); runInRuntime(array); } private static String getFilePath(String str) { return System.getProperty("user.dir") + str; } private void runInRuntime(String[] commands) { try { process = Runtime.getRuntime().exec(commands); StreamWatch outWathch = new StreamWatch(process.getInputStream(), OUT_TYEP.OUT); StreamWatch errorWathch = new StreamWatch(process.getErrorStream(), OUT_TYEP.ERROR); outWathch.start(); errorWathch.start(); } catch (Exception e) { e.printStackTrace(); } } public static List<OpenCLDevice> getCLDevices() { List<OpenCLDevice> openCLDevices = new ArrayList<OpenCLDevice>(); String command = ""; if (OSUtils.isMac()) { command = getFilePath(MAC_OS_PATH + MAC_LINUX_OCLVANITYGEN); } else if (OSUtils.isLinux()) { command = getFilePath(LINUX_PATH + MAC_LINUX_OCLVANITYGEN); } else if (OSUtils.isWindows()) { command = getFilePath(WINDOWS_PATH + WINDOWS_OCLVANITYGEN); } try { String line = null; BufferedReader stdout = null; //list the files and directorys under C:\ Process p = Runtime.getRuntime().exec(new String[]{command, "-d 1000", "1LLL"}); stdout = new BufferedReader(new InputStreamReader(p .getErrorStream())); List<String> availableList = new ArrayList<String>(); while ((line = stdout.readLine()) != null) { if (matcherAvailable(line)) { availableList.add(line); } } stdout.close(); int platform = 0; String platformName = ""; int device = 0; String deviceName = ""; for (String str : availableList) { if (str.startsWith(" ")) { String[] devices = str.split(":"); device = Integer.valueOf(devices[0].trim()); deviceName = devices[1].trim(); OpenCLDevice openCLDevice = new OpenCLDevice(platform, device, platformName, deviceName); openCLDevices.add(openCLDevice); } else { String[] platforms = str.split(":"); platform = Integer.valueOf(platforms[0].trim()); platformName = platforms[1].trim(); } } } catch (IOException e) { e.printStackTrace(); } return openCLDevices; } private static boolean matcherAvailable(String str) { Pattern p = Pattern.compile(AVAILABLE_OPENCL_FORMAT); Matcher matcher = p.matcher(str); return matcher.find(); } private void dealErrorWithString(String line) { if (Utils.isEmpty(line)) { return; } if (line.contains(DIFFICULTY_FORMAT)) { if (vanitygenListener != null) { vanitygenListener.onDifficulty(line.replace(DIFFICULTY_FORMAT, "").trim()); } return; } } private void dealOutWithString(String line) { if (Utils.isEmpty(line)) { return; } Pattern p = Pattern.compile(PROGRESS_FORMAT); Matcher matcher = p.matcher(line); if (matcher.find()) { if (vanitygenListener != null) { vanitygenListener.onProgress(matcher.group(1), Long.valueOf(matcher.group(2)), Double.valueOf(matcher.group(3)), Integer.valueOf(matcher.group(4)), matcher.group(5)); } } if (line.contains(ADDRESS_FORMAT)) { if (vanitygenListener != null) { vanitygenListener.getAddress(line.replace(ADDRESS_FORMAT, "").trim()); } return; } if (line.contains(PRIVATE_FORMAT)) { generatedKey = true; if (vanitygenListener != null) { vanitygenListener.getPrivateKey(line.replace(PRIVATE_FORMAT, "").trim(), (System.currentTimeMillis() - beginTime)); } } } public void stop() { if (process != null) { process.destroy(); } } private class StreamWatch extends Thread { InputStream is; private OUT_TYEP outTyep; StreamWatch(InputStream is, OUT_TYEP outTyep) { this.is = is; this.outTyep = outTyep; } public void run() { try { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line = null; while ((line = br.readLine()) != null) { if (outTyep == OUT_TYEP.OUT) { dealOutWithString(line); } else { dealErrorWithString(line); } LogUtil.printlnOut("line:" + line); } is.close(); if (this.outTyep == OUT_TYEP.OUT) { if (!generatedKey) { if (vanitygenListener != null) { vanitygenListener.error(LocaliserUtils.getString("vanity_generated_failed")); } } } } catch (IOException ioe) { ioe.printStackTrace(); } } } }