All Downloads are FREE. Search and download functionalities are using the official Maven repository.

club.zhcs.utils.system.HardWares Maven / Gradle / Ivy

package club.zhcs.utils.system;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Optional;

import org.nutz.lang.Files;
import org.nutz.lang.Lang;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;

/**
 * @author Kerbores([email protected])
 *
 */
@Log4j2
public class HardWares {

    private static final String CSCRIPT_NOLOGO = "cscript //NoLogo ";

    /**
     * 
     */
    private HardWares() {}

    /**
     * 获取主板序列号
     * 
     * @return 主板序列号
     */
    private static String getMotherboardSN() {
        StringBuilder result = new StringBuilder();
        try {
            File file = File.createTempFile("realhowto", ".vbs");
            file.deleteOnExit();
            String vbs = "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
                         + "Set colItems = objWMIService.ExecQuery _ \n"
                         + "   (\"Select * from Win32_BaseBoard\") \n"
                         + "For Each objItem in colItems \n"
                         + "    Wscript.Echo objItem.SerialNumber \n"
                         + "    exit for  ' do the first cpu only! \n"
                         + "Next \n";

            Files.write(file, vbs);
            String path = file.getPath().replace("%20", " ");
            Process p = Runtime.getRuntime()
                               .exec(
                                     CSCRIPT_NOLOGO
                                     + path);
            BufferedReader input = new BufferedReader(new InputStreamReader(
                                                                            p.getInputStream()));
            String line;
            while ((line = input.readLine()) != null) {
                result.append(line);
            }
            input.close();
        }
        catch (Exception e) {
            throw Lang.wrapThrow(e);
        }
        return result.toString().trim();
    }

    /**
     * 获取硬盘序列号(该方法获取的是 盘符的逻辑序列号,并不是硬盘本身的序列号) 硬盘序列号还在研究中
     * 
     * @param drive
     *            盘符
     * @return 硬盘序列号
     */
    private static String getHardDiskSN(String drive) {
        StringBuilder result = new StringBuilder();
        try {
            File file = File.createTempFile("realhowto", ".vbs");
            file.deleteOnExit();

            String vbs = "Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\n"
                         + "Set colDrives = objFSO.Drives\n"
                         + "Set objDrive = colDrives.item(\""
                         + drive
                         + "\")\n"
                         + "Wscript.Echo objDrive.SerialNumber"; // see note

            Files.write(file, vbs);
            String path = file.getPath().replace("%20", " ");
            Process p = Runtime.getRuntime()
                               .exec(
                                     CSCRIPT_NOLOGO
                                     + path);
            BufferedReader input = new BufferedReader(new InputStreamReader(
                                                                            p.getInputStream()));
            String line;
            while ((line = input.readLine()) != null) {
                result.append(line);
            }
            input.close();
        }
        catch (Exception e) {
            throw Lang.wrapThrow(e);
        }
        return result.toString().trim();
    }

    /**
     * 获取CPU序列号
     * 
     * @return CPU序列号
     */
    private static String getCPUSerial() {
        StringBuilder result = new StringBuilder();
        try {
            File file = File.createTempFile("tmp", ".vbs");
            file.deleteOnExit();
            String vbs = "Set objWMIService = GetObject(\"winmgmts:\\\\.\\root\\cimv2\")\n"
                         + "Set colItems = objWMIService.ExecQuery _ \n"
                         + "   (\"Select * from Win32_Processor\") \n"
                         + "For Each objItem in colItems \n"
                         + "    Wscript.Echo objItem.ProcessorId \n"
                         + "    exit for  ' do the first cpu only! \n"
                         + "Next \n";

            Files.write(file, vbs);
            String path = file.getPath().replace("%20", " ");
            Process p = Runtime.getRuntime()
                               .exec(
                                     CSCRIPT_NOLOGO
                                     + path);
            BufferedReader input = new BufferedReader(new InputStreamReader(
                                                                            p.getInputStream()));
            String line;
            while ((line = input.readLine()) != null) {
                result.append(line);
            }
            input.close();
        }
        catch (Exception e) {
            e.fillInStackTrace();
        }
        if (result.toString().trim().length() < 1) {
            return "无CPU_ID被读取";
        }
        return result.toString().trim();
    }

    private static List getLocalHostLANAddress() throws SocketException {
        List ips = new ArrayList<>();
        Enumeration interfs = NetworkInterface.getNetworkInterfaces();
        while (interfs.hasMoreElements()) {
            NetworkInterface interf = interfs.nextElement();
            Enumeration addres = interf.getInetAddresses();
            while (addres.hasMoreElements()) {
                InetAddress in = addres.nextElement();
                if (in instanceof Inet4Address) {
                    log.debug("v4:" + in.getHostAddress());
                    if (!"127.0.0.1".equals(in.getHostAddress())) {
                        ips.add(in.getHostAddress());
                    }
                }
            }
        }
        return ips;
    }

    /**
     * MAC 通过jdk自带的方法,先获取本机所有的ip,然后通过NetworkInterface获取mac地址
     * 
     * @return MAC
     */
    private static String getMac() {
        try {
            StringBuilder resultStr = new StringBuilder();
            List ls = getLocalHostLANAddress();
            for (String str : ls) {
                InetAddress ia = InetAddress.getByName(str);// 获取本地IP对象
                // 获得网络接口对象(即网卡),并得到mac地址,mac地址存在于一个byte数组中。
                byte[] mac = NetworkInterface.getByInetAddress(ia)
                                             .getHardwareAddress();
                // 下面代码是把mac地址拼装成String
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < mac.length; i++) {
                    if (i != 0) {
                        sb.append("-");
                    }
                    // mac[i] & 0xFF 是为了把byte转化为正整数
                    String s = Integer.toHexString(mac[i] & 0xFF);
                    sb.append(s.length() == 1 ? 0 + s : s);
                }
                // 把字符串所有小写字母改为大写成为正规的mac地址并返回
                resultStr.append(sb.toString().toUpperCase() + ",");
            }
            return resultStr.toString();
        }
        catch (Exception e) {
            throw Lang.wrapThrow(e);
        }
    }

    /*************************** linux *********************************/

    /**
     * 运行命令
     * 
     * @param cmd
     *            命令
     * @return 返回
     */
    private static String executeLinuxCmd(String cmd) {
        try {
            log.debug("got cmd job : " + cmd);
            Runtime run = Runtime.getRuntime();
            Process process;
            process = run.exec(cmd);
            InputStream in = process.getInputStream();
            StringBuilder out = new StringBuilder();
            byte[] b = new byte[8192];
            for (int n; (n = in.read(b)) != -1;) {
                out.append(new String(b, 0, n));
            }

            in.close();
            process.destroy();
            return out.toString();
        }
        catch (Exception e) {
            throw Lang.wrapThrow(e);
        }
    }

    /**
     * 
     * @param cmd
     *            命令语句
     * @param record
     *            要查看的字段
     * @param symbol
     *            分隔符
     * @return 序列号
     */
    private static String getSerialNumber(String cmd, String record, String symbol) {
        String execResult = executeLinuxCmd(cmd);
        String[] infos = execResult.split("\n");

        for (String info : infos) {
            info = info.trim();
            if (info.indexOf(record) != -1) {
                info = info.replace(" ", "");
                String[] sn = info.split(symbol);
                return sn[1];
            }
        }

        return null;
    }

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class HardWare {
        String cpuid;
        String diskid;
        String mac;
        String mainboard;
    }

    static HardWare hardWare;

    static {
        hardWare = getAllSn();
    }

    public static HardWare hardWare() {
        return hardWare;
    }

    public static String getMacUUID() {
        String result = "";
        BufferedReader bufferedReader = null;
        Process p = null;
        try {
            p = Runtime.getRuntime().exec(new String[]{"sh", "-c", "system_profiler SPHardwareDataType"});// 管道
            bufferedReader = new BufferedReader(new InputStreamReader(
                                                                      p.getInputStream()));
            String line = null;
            int index = -1;
            while ((line = bufferedReader.readLine()) != null) {
                // 寻找标示字符串[hwaddr]
                index = line.toLowerCase().indexOf("uuid");
                if (index >= 0) {// 找到了
                    // 取出mac地址并去除2边空格
                    result = line.substring(index + "uuid".length() + 1).trim();
                    break;
                }
            }

        }
        catch (IOException e) {
            log.error("获取cpu信息错误", e);
        }
        return result.trim();
    }

    /**
     * 获取CPUID、硬盘序列号、MAC地址、主板序列号
     * 
     * @return 硬件序列号信息
     */
    private static HardWare getAllSn() {
        String os = System.getProperty("os.name");
        os = os.toUpperCase();
        log.debug(os);

        if (os.startsWith("LINUX")) {
            log.debug("=============>for linux");
            String cpuid = getSerialNumber("dmidecode -t processor | grep 'ID'", "ID", ":");
            log.debug("cpuid : " + cpuid);
            String mainboardNumber = getSerialNumber("dmidecode |grep 'Serial Number'", "Serial Number", ":");
            log.debug("mainboardNumber : " + mainboardNumber);
            String diskNumber = getSerialNumber("fdisk -l", "Disk identifier", ":");
            log.debug("diskNumber : " + diskNumber);
            String mac = getSerialNumber("ifconfig -a", "ether", " ");

            return HardWare.builder()
                           .cpuid(Optional.ofNullable(cpuid).orElse("").toUpperCase().replace(" ", "-"))
                           .diskid(Optional.ofNullable(diskNumber).orElse("").toUpperCase().replace(" ", "-"))
                           .mac(Optional.ofNullable(mac).orElse("").toUpperCase().replace(" ", "-"))
                           .mainboard(Optional.ofNullable(mainboardNumber).orElse("").toUpperCase().replace(" ", "-"))
                           .build();
        } else if (os.startsWith("WINDOWS")) {
            log.debug("=============>for windows");
            String cpuid = getCPUSerial();
            String mainboard = getMotherboardSN();
            String disk = getHardDiskSN("c");
            String mac = getMac();

            log.debug("CPU  SN:" + cpuid);
            log.debug("主板  SN:" + mainboard);
            log.debug("C盘   SN:" + disk);
            log.debug("MAC  SN:" + mac);

            return HardWare.builder()
                           .cpuid(cpuid.toUpperCase().replace(" ", "-"))
                           .diskid(disk.toUpperCase().replace(" ", "-"))
                           .mac(mac.toUpperCase().replace(" ", "-"))
                           .mainboard(mainboard.toUpperCase().replace(" ", "-"))
                           .build();
        } else {
            return HardWare.builder()
                           .cpuid(getMacUUID())
                           .build();
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy