`

(转)JAVA获得机器码的实现

 
阅读更多
http://yangshangchuan.iteye.com/blog/2012401

首先,定义了一个统一的接口,以支持不同操作系统不同实现的透明切换:

Java代码  收藏代码
/**
*生成机器码的接口,不同平台有不同实现
* @author 杨尚川
*/ 
public interface SequenceService { 
    /**
     * 获取机器码
     * @return  机器码
     */ 
    public String getSequence();     



其次,定义了一个抽象类,实现了一些通用的功能,如生成MD5摘要、将很长的字符串以固定的位数分割开,以便于人类阅读(如将机器码 71F5DA7F495E7F706D47F3E63DC6349A 每4个一组,以-分割为71F5-DA7F-495E-7F70-6D47-F3E6-3DC6-349A)、利用sigar来生成机器码。这里需要在pom.xml中加入sigar依赖。

Xml代码  收藏代码
<dependency> 
    <groupId>org.fusesource</groupId> 
    <artifactId>sigar</artifactId> 
    <version>1.6.4</version> 
    <exclusions> 
        <exclusion> 
            <groupId>log4j</groupId> 
            <artifactId>log4j</artifactId> 
        </exclusion> 
    </exclusions> 
</dependency> 


Java代码  收藏代码
import org.apdplat.module.system.service.PropertyHolder; 
import org.apdplat.platform.log.APDPlatLogger; 
import org.apdplat.platform.util.ConvertUtils; 
import org.apdplat.platform.util.FileUtils; 
import java.io.File; 
import java.io.UnsupportedEncodingException; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.util.HashSet; 
import java.util.Properties; 
import java.util.Set; 
import org.apdplat.platform.log.APDPlatLoggerFactory; 
import org.hyperic.sigar.Mem; 
import org.hyperic.sigar.NetFlags; 
import org.hyperic.sigar.NetInterfaceConfig; 
import org.hyperic.sigar.Sigar; 
 
/**
*机器码生成的通用服务
* @author 杨尚川
*/ 
public abstract class AbstractSequenceService   implements SequenceService{ 
    protected final APDPlatLogger LOG = APDPlatLoggerFactory.getAPDPlatLogger(getClass()); 
    /**
     * 对一段String生成MD5摘要信息
     * @param message 要摘要的String
     * @return 生成的MD5摘要信息
     */ 
    protected String getMD5(String message) { 
        message += "{apdplat}"; 
        try { 
            MessageDigest md = MessageDigest.getInstance("MD5"); 
            LOG.debug("MD5摘要长度:" + md.getDigestLength()); 
            byte[] b = md.digest(message.getBytes("utf-8")); 
            String md5 = ConvertUtils.byte2HexString(b)+message.length(); 
            return getSplitString(md5); 
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { 
            LOG.error("MD5摘要失败",e); 
        } 
        return null; 
    } 
    /**
     * 将很长的字符串以固定的位数分割开,以便于人类阅读
     * @param str
     * @return 
     */ 
    protected String getSplitString(String str){  
        return getSplitString(str, "-", 4); 
    } 
    /**
     * 将很长的字符串以固定的位数分割开,以便于人类阅读
     * 如将
     * 71F5DA7F495E7F706D47F3E63DC6349A
     * 以-,每4个一组,则分割为
     * 71F5-DA7F-495E-7F70-6D47-F3E6-3DC6-349A
     * @param str 字符串
     * @param split 分隔符
     * @param length 长度
     * @return 
     */ 
    protected String getSplitString(String str, String split, int length){         
        int len=str.length(); 
        StringBuilder temp=new StringBuilder(); 
        for(int i=0;i<len;i++){ 
            if(i%length==0 && i>0){ 
                temp.append(split); 
            } 
            temp.append(str.charAt(i)); 
        } 
        String[] attrs=temp.toString().split(split); 
        StringBuilder finalMachineCode=new StringBuilder(); 
        for(String attr : attrs){ 
            if(attr.length()==length){ 
                finalMachineCode.append(attr).append(split); 
            } 
        } 
        String result=finalMachineCode.toString().substring(0, finalMachineCode.toString().length()-1); 
        return result; 
    }     
    /**
     * 利用sigar来生成机器码,当然这个实现不是很好,无法获得CPU ID,希望有兴趣的朋友来改进这个实现
     * @param osName 操作系统类型
     * @return 机器码
     */ 
    protected String getSigarSequence(String osName) { 
        try { 
            File libFile = new File(FileUtils.getAbsolutePath("/WEB-INF/lib/"+PropertyHolder.getProperty("libsigar."+osName))); 
            LOG.debug("libsigar."+osName+" : "+libFile.getAbsolutePath()); 
             
            System.load(libFile.getAbsolutePath()); 
            Set<String> result = new HashSet<>(); 
            Sigar sigar = new Sigar(); 
            String[] ifaces = sigar.getNetInterfaceList(); 
            for (String iface : ifaces) { 
                NetInterfaceConfig cfg = sigar.getNetInterfaceConfig(iface);                if (NetFlags.LOOPBACK_ADDRESS.equals(cfg.getAddress()) || (cfg.getFlags() & NetFlags.IFF_LOOPBACK) != 0 
                        || NetFlags.NULL_HWADDR.equals(cfg.getHwaddr())) { 
                    continue; 
                } 
                String mac = cfg.getHwaddr(); 
                result.add(mac); 
                LOG.debug("mac: " + mac); 
            } 
            if(result.size()<1){ 
                return null; 
            } 
            Properties props = System.getProperties(); 
            String javaVersion = props.getProperty("java.version"); 
            result.add(javaVersion); 
            LOG.debug("Java的运行环境版本:    " + javaVersion); 
            String javaVMVersion = props.getProperty("java.vm.version"); 
            result.add(javaVMVersion); 
            LOG.debug("Java的虚拟机实现版本:    " + props.getProperty("java.vm.version")); 
            String osVersion = props.getProperty("os.version"); 
            result.add(osVersion); 
            LOG.debug("操作系统的版本:    " + props.getProperty("os.version")); 
 
            Mem mem = sigar.getMem(); 
            // 内存总量 
            String totalMem = mem.getTotal() / 1024L + "K av"; 
            LOG.debug("内存总量:    " + totalMem); 
            result.add(totalMem); 
 
            LOG.debug("result:    " + result); 
            String machineCode = getMD5(result.toString()); 
 
            return machineCode; 
        } catch (Throwable ex) { 
            LOG.error("生成 "+osName+" 平台下的机器码失败", ex); 
        } 
        return null; 
    } 



最后,我们分别看看不同平台的实现。

Windows:

Java代码  收藏代码
/**
*在Windows平台上生成机器码
* @author 杨尚川
*/ 
public final class WindowsSequenceService extends AbstractSequenceService{     
    @Override 
    public String getSequence() {         
        String cpuID=getCPUSerial(); 
        String hdID=getHDSerial("C"); 
        if(cpuID==null || hdID==null){ 
            return null; 
        } 
        String machineCode = getMD5(cpuID+hdID); 
                 
        return machineCode; 
    } 
     
    /**
     *
     * @param drive 硬盘驱动器分区 如C,D
     * @return 该分区的卷标
     */ 
    private String getHDSerial(String drive) { 
        StringBuilder result = new StringBuilder(); 
        try { 
            File file = File.createTempFile("tmp", ".vbs"); 
            file.deleteOnExit(); 
            try (FileWriter fw = new java.io.FileWriter(file)) { 
                String vbs = "Set objFSO = CreateObject(\"Scripting.FileSystemObject\")\n" 
                        + "Set colDrives = objFSO.Drives\n" + "Set objDrive = colDrives.item(\"" + drive + "\")\n" 
                        + "Wscript.Echo objDrive.SerialNumber"; 
                fw.write(vbs); 
            } 
            Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath()); 
            try (BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()))) { 
                String line; 
                while ((line = input.readLine()) != null) { 
                    result.append(line); 
                } 
            } 
            file.delete(); 
        } catch (Throwable e) { 
            LOG.error("生成HDSerial失败", e); 
        } 
        if (result.length() < 1) { 
            LOG.info("无磁盘ID被读取"); 
        } 
 
        return result.toString(); 
    } 
 
    /**
     * 获取CPU号,多CPU时,只取第一个
     * @return
     */ 
    private String getCPUSerial() { 
        StringBuilder result = new StringBuilder(); 
        try { 
            File file = File.createTempFile("tmp", ".vbs"); 
            file.deleteOnExit(); 
            try (FileWriter fw = new FileWriter(file)) { 
                String vbs = "On Error Resume Next \r\n\r\n" + "strComputer = \".\"  \r\n" 
                        + "Set objWMIService = GetObject(\"winmgmts:\" _ \r\n" 
                        + "    & \"{impersonationLevel=impersonate}!\\\\\" & strComputer & \"\\root\\cimv2\") \r\n" 
                        + "Set colItems = objWMIService.ExecQuery(\"Select * from Win32_Processor\")  \r\n " 
                        + "For Each objItem in colItems\r\n " + "    Wscript.Echo objItem.ProcessorId  \r\n " 
                        + "    exit for  ' do the first cpu only! \r\n" + "Next                    "; 
 
                fw.write(vbs); 
            } 
            Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath()); 
            try (BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()))) { 
                String line; 
                while ((line = input.readLine()) != null) { 
                    result.append(line); 
                } 
            } 
            file.delete(); 
        } catch (Throwable e) { 
            LOG.error("生成CPUSerial失败", e); 
        } 
        if (result.length() < 1) { 
            LOG.info("无CPU_ID被读取"); 
        } 
        return result.toString(); 
    } 
     
    public static void main(String[] args) {         
        SequenceService s = new WindowsSequenceService(); 
        String seq = s.getSequence(); 
        System.out.println(seq); 
    } 



Linux:

Java代码  收藏代码
/**
*在Linux平台上生成机器码
* @author 杨尚川
*/ 
public class LinuxSequenceService  extends AbstractSequenceService{ 
    @Override 
    public String getSequence() { 
        return getSigarSequence("linux"); 
    } 
 
    public static void main(String[] args) { 
        SequenceService s = new LinuxSequenceService(); 
        String seq = s.getSequence(); 
        System.out.println(seq); 
    } 



Mac OS X:

Java代码  收藏代码
/**
*在Mac OS X平台上生成机器码
* @author 杨尚川
*/ 
public class MacSequenceService    extends AbstractSequenceService{ 
    @Override 
    public String getSequence() { 
        return getSigarSequence("mac"); 
    } 
    
    public static void main(String[] args) { 
        SequenceService s = new MacSequenceService(); 
        String seq = s.getSequence(); 
        System.out.println(seq); 
    } 



Solaris:

Java代码  收藏代码
/**
*在Solaris平台上生成机器码
* @author 杨尚川
*/ 
public class SolarisSequenceService    extends AbstractSequenceService{ 
    @Override 
    public String getSequence() { 
        return getSigarSequence("solaris"); 
    } 
 
    public static void main(String[] args) { 
        SequenceService s = new SolarisSequenceService(); 
        String seq = s.getSequence(); 
        System.out.println(seq); 
    }     

分享到:
评论
1 楼 masuweng 2018-03-15  
        

相关推荐

    机器码生成注册码教程终稿.pdf

    以下是使用Java语言获取CPU序列号和硬盘卷标号的代码实现: #region 获取 cpu 的序列号 public string getCpu() { string strCpu = null; ManagementClass myCpu = new ManagementClass("win32_Processor"); ...

    java实现电脑端扫描二维码

    在Java中实现电脑端扫描二维码的过程涉及到多个步骤,包括前端的图像捕获、后端的图像处理和解码。以下是对这些步骤的详细说明: 1. **前端图像捕获**: - 前端使用JavaScript来调用电脑摄像头进行拍照。这通常...

    扫码枪扫码Java程序.zip

    java程序编写获取扫码枪扫码程序,并将扫码枪扫码有数据库MySQL数据进行对比预警,解决相关行业使用扫码枪进行出货重复使用相关商品码问题。该程序连接MySQL数据库,可同时部署到多台机器上进行设备比对。底层也实现...

    java反编译软件 class转java

    这就引出了我们的主题——"java反编译软件 class转java"。 反编译是将已编译的机器代码转换回源代码的过程。在Java世界里,这个过程就是将.class文件转换回.java文件。这样的工具可以帮助开发者查看和理解已有的...

    Java 字节码概述

    当 JVM 得到一个 Java 字节码应用程序后,便为该代码中一个类的每一个方法创建一个栈框架,以保存该方法的状态信息。每个栈框架包括以下三类信息: * 局部变量:是被组织为一个以字长为单位、从 0 开始计数的数组。...

    myeclipse注册码java生成类

    在提供的文件列表中,有一个名为`Key.java`的文件,这很可能是一个Java类,用于实现上述注册码生成的过程。分析这个类的源代码可以帮助我们理解具体的实现细节,例如使用的加密算法、数据组合方式等。不过,由于当前...

    我的通讯录管理系统java实现

    《我的通讯录管理系统Java实现详解》 通讯录管理系统是一个实用的应用程序,用于存储、管理和查找个人联系信息。本文将深入探讨一个基于Java实现的通讯录管理系统,包括其核心功能、技术选型以及如何在Eclipse环境...

    Java 字节码简单说明.zip

    为了提高性能,现代JVM还引入了即时编译(Just-In-Time, JIT)技术,当热点代码被频繁执行时,JVM会将其编译成本地机器码,从而获得更快的执行速度。 字节码的几个关键概念包括: 1. 操作数栈:字节码指令执行时会...

    Java转exe工具

    这些工具能够将Java字节码包装在一个Windows可执行的外壳中,模拟JVM的行为,使得Java程序能在没有安装JRE的机器上运行。不过需要注意的是,虽然转换后的.exe文件可以独立运行,但仍然依赖于Java运行时组件,只是...

    编译原理词法分析,语法分析,中间代码生成四元式的java实现

    在这个Java实现中,会生成并存储四元式,这可能是通过分析语法树,对每个节点进行遍历和转换得到的。四元式的生成有助于后续步骤,如静态类型检查、优化和代码生成。中间代码的可读性对于调试和教学也非常有帮助。 ...

    Java2024突击面试手册(备战2024)

    Java解释器首先逐行解释字节码,但对于频繁执行的热点代码,JVM会使用JIT(Just-In-Time)编译器将字节码编译为机器码,以提高性能。JDK 9引入了AOT(Ahead of Time Compilation)编译模式,允许预先将字节码编译为...

    X86指令解析-java实现

    1. **二进制提取**:读取EXE文件,这些文件包含了机器码,即实际的X86指令。 2. **解包和脱壳**:可能需要处理程序的保护机制,如压缩、加密或加壳,以便访问原始指令。 3. **指令识别**:识别每个字节序列对应的...

    java实现人脸识别

    在Java中实现人脸识别技术主要涉及图像处理、模式识别和机器学习等领域的知识。人脸识别作为一种生物特征识别技术,近年来在安全认证、智能门禁、社交媒体等领域得到了广泛应用。在本项目中,我们将利用百度云API来...

    Java虚拟机解释执行机制研究.pdf

    JVM解释执行机制是Java虚拟机执行字节码的一种方式,其中解释器将Java字节码逐条转换成机器码并执行。 Java语言的跨平台特性得益于其编译后不是直接生成特定平台上的机器码,而是生成一种中间形式的字节码。Java源...

    JAVAocr图像网页附加码解析读取

    这个库提供了与Tesseract引擎交互的API,使得开发者能够方便地在Java程序中实现图像到文本的转换。 首先,我们需要在Java项目中集成Java Tesseract库。这通常涉及到添加库的依赖,如Maven或Gradle的配置,确保项目...

    java连接数据库实现增删改查 教师管理系统

    在Java编程中,连接数据库并实现增删改查(CRUD)操作是常见的任务,尤其在构建管理系统如教师管理系统时。下面将详细讲解这个过程涉及的关键知识点。 首先,要连接数据库,我们需要使用Java的JDBC(Java Database ...

    如何利用JNI实现Java插件开发

    这些文件包含了C++代码的机器码,可以直接被操作系统加载执行。 2. **打包动态链接库至JAR文件:** - 将这些DLL和SO文件打包进JAR文件中,以便于Java应用程序能够方便地调用它们。这是因为Java应用通常是以JAR...

    java和汇编源程序

    1. 转换:Java源代码(.java文件)通过Java编译器(javac)转换为字节码(.class文件),而汇编源代码(.asm或.asm文件)则通过汇编器转化为机器码(.obj或.exe文件)。 2. 交互:虽然通常不直接混合编写,但在某些...

    Java 中文文本摘要生成

    在IT领域,文本摘要生成是一项重要的自然语言处理任务,它涉及到机器学习、人工智能以及信息检索等多个子领域。本文主要探讨的是如何在Java环境下利用jieba分词库来实现中文文本的摘要生成。jieba是一个非常流行的...

    Java开发示例代码

    10. **Java程序的运行**:Java程序在JVM上运行,编译后得到的是字节码,而不是机器码,因此Java程序可以跨平台运行。 11. **方法的静态修饰**:要使类名可以直接调用一个方法,需要使用`static`关键字修饰该方法。 ...

Global site tag (gtag.js) - Google Analytics