import java.io.*;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.*; /**
* 注意事项:
* ① 通过执行vbs 脚本(基于微软 Visual Basic的脚本语言) 来获取信息的方式只适用于windows系统,因为这种方式极度依赖 Windows脚本宿主环境的支持
* ② 关于临时目录,可通过 System.getProperty("java.io.tmpdir") 获取其具体位置。在window下通常为 C:\Users\Administrator\AppData\Local\Temp ,linux系统 下为 /tmp
* ③ 命令方式和执行vbs 脚本的方式获取到的磁盘序列号并不相同,具体哪个是真实的序列号,有待验证
* ④ 或可尝试通过arp 命令来获取物理地址,但是arp查询的是高速缓存表的IP-MAC映射关系,包括了网络中与本机通信过的所有主机的MAC-IP映射关系(你可以ping一下远程主机建立相应的映射关系缓存),获取的地址信息或显得过于庞杂
* ⑤ 针对 Linux 系统主要通过执行命令的方式,不过由于系统架构的差异性,不同平台对同样的命令不一定都支持,需要根据具体系统测试、做兼容,这里提供一些常用查看命令——
* MAC 地址:ip link | grep link/ether | awk '{print $2}'
* 磁盘序列号 hdparm -i /dev/sda | grep SerialNo 或 lsblk -a -o SERIAL
* CPU序列号 dmidecode -t processor | grep 'ID'
*/ public class NetworkUtil {
/**
* 通过执行vbs 脚本获取系统主板序列号
*/
public static String getMotherboardSerialByVbs() {
StringBuilder result = new StringBuilder();
try {
File file = File.createTempFile("realhowto", ".vbs");
file.deleteOnExit();
FileWriter fw = new FileWriter(file);
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";
fw.write(vbs);
fw.close();
// Nologo 无标识执行 vbs 脚本
Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
result.append(line);
}
input.close();
} catch (Exception e) {
e.printStackTrace();
}
return result.toString().trim();
} /**
* 通过执行 vbs 脚本(基于微软 Visual Basic的脚本语言) 来获磁盘序列号
*/
public static String getWindowsDiskSerialByVbs() {
StringBuilder result = new StringBuilder();
try {
// 默认目录下创建临时文件,自己在任意位置创建vbs文件执行都可以
File file = File.createTempFile("tmp", ".vbs");
// 虚拟机退出时删除临时目录
file.deleteOnExit();
FileWriter fw = new FileWriter(file);
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";
fw.write(vbs);
fw.flush();
fw.close();
Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
result.append(line);
}
input.close();
} catch (Exception e) {
e.printStackTrace();
}
return result.toString().trim();
} /**
* 通过 vbs 脚本获取分区标记序列号,该序列号是由操作系统在格式化驱动器时创建的,而不是制造商的硬件序列号。 可参见 https://www.rgagnon.com/javadetails/java-0580.html
*/
public static String getWindowsDiskSerialByVbs(String drive) {
StringBuilder result = new StringBuilder();
try {
File file = File.createTempFile("tmp", ".vbs");
file.deleteOnExit();
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);
fw.close();
Process p = Runtime.getRuntime().exec("cscript //NoLogo " + file.getPath());
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = input.readLine()) != null) {
result.append(line);
}
input.close();
} catch (Exception e) {
e.printStackTrace();
}
return result.toString().trim();
} /**
* 通过 cmd 命令获取序列号,不同Windows系统系统获取的序列号格式不尽一致,请自行测试
* ① 获取 磁盘 序列号
* wmic diskdrive get Serialnumber
* wmic path win32_physicalmedia get SerialNumber
* wmic path Win32_DiskDrive get SerialNumber
* ② 获取 主板 序列号
* wmic baseboard get Serialnumber
* ③ 获取 CPU 序列号
* wmic cpu get processorid
*/
public static String getWindowsSerialByCmd(String cmd) {
try {
Process process = Runtime.getRuntime().exec(cmd);
InputStream inputStream = process.getInputStream();
Scanner scanner = new Scanner(inputStream);
scanner.next();
return scanner.next();
} catch (IOException ex) {
ex.printStackTrace();
}
return "";
} /**
* 在 Linux 上获取序列号
* lsblk -a -o SERIAL 在红帽系统(Red Hat)和基于红帽的CentOS虚拟机系统, 龙芯系统(mips64)上可以成功获取,但在 arm 系统 armv7l 等架构的某些机器中无法成功获取 不同平台获取的格式需要进行针对性的处理
*/
public static String getDiskSerial(String cmd) {
String execResult = getLinuxSerialByCmd(cmd);
if (execResult == null)
throw new RuntimeException("设备不支持该命令获取!");
String[] infos = execResult.split("\n");
if (infos.length > 1) {
return infos[infos.length - 1];
}
return null;
} /**
* 获取本地主机所有 IPv4 地址列表
* 注意事项: 由于NetworkInterface 只能枚举已启用的网卡信息,所以该方法只能获取到设备上已启用的网卡的 IP 地址
*/
public static List<String> getLocalHostIPv4Addr() throws SocketException {
List<String> ips = new ArrayList<>();
// 本机所有网络接口列表 这里有个坑,枚举出来的其实只是已经启用的网络接口 ,在Linux系统上也即 ifconfig 能看到的,通过 ip link 才能查看所有网络接口
Enumeration<NetworkInterface> enums = NetworkInterface.getNetworkInterfaces();
while (enums.hasMoreElements()) {
NetworkInterface networkInterface = enums.nextElement();
// 枚举网络接口上所有地址的列表 一个网络接口可以绑定多个IP地址
Enumeration<InetAddress> addres = networkInterface.getInetAddresses();
while (addres.hasMoreElements()) {
InetAddress inetAddress = addres.nextElement();
// 只查询IPv4地址接口,排除了IPv6和回送地址
String hostAddress = inetAddress.getHostAddress();
if (inetAddress instanceof Inet4Address && !"127.0.0.1".equals(hostAddress)) {
ips.add(hostAddress);
}
}
}
return ips;
} /**
* 根据 IP 获取物理地址
*
* @param bytes 原始 IP
* @return mac 地址
*/
public static String getMacByIp(byte[] bytes) {
try {
InetAddress inetAddress = InetAddress.getByAddress(bytes);
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(inetAddress);
byte[] hardwareAddress = networkInterface.getHardwareAddress();
return formartMac(hardwareAddress);
} catch (Exception e) {
e.printStackTrace();
}
return null;
} /**
* 根据 IP 获取物理地址
*
* @param ip 点分四段 IP 地址
* @return mac 地址
*/
public static String getMacByIp(String ip) {
try {
InetAddress inetAddress = InetAddress.getByName(ip);
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(inetAddress);
byte[] hardwareAddress = networkInterface.getHardwareAddress();
return formartMac(hardwareAddress);
} catch (Exception e) {
e.printStackTrace();
}
return null;
} /**
* 根据 网卡名 获取物理地址
*
* @param eth 网卡名
* @return mac 地址
*/
public static String getMacByNetCard(String eth) {
try {
NetworkInterface networkInterface = NetworkInterface.getByName(eth);
byte[] hardwareAddress = networkInterface.getHardwareAddress();
return formartMac(hardwareAddress);
} catch (Exception e) {
e.printStackTrace();
}
return null;
} /**
* mac 地址格式化
*/
private static String formartMac(byte[] bytes) {
if (bytes == null || bytes.length == 0)
return "";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
if (i != 0) {
sb.append("-");
}
String temp = Integer.toHexString(bytes[i] & 0xFF);
sb.append(temp.length() == 1 ? (0 + temp) : temp);
}
return sb.toString().toUpperCase();
} /**
* 命令执行
*/
private static String getLinuxSerialByCmd(String cmd) {
try {
Runtime run = Runtime.getRuntime();
Process process = run.exec(cmd);
InputStream in = process.getInputStream();
StringBuilder sb = new StringBuilder();
byte[] b = new byte[1024];
for (int n; (n = in.read(b)) != -1;) {
sb.append(new String(b, 0, n));
}
in.close();
process.destroy();
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
} }

记MAC地址、磁盘序列号的获取的更多相关文章

  1. C#获得MAC地址(网卡序列号)代码

    代码如下: //获得网卡序列号 //MAc地址 http://www.cnblogs.com/sosoft/ public string GetMoAddress() { string MoAddre ...

  2. MAC地址,使用java获取IP地址和MAC地址。

    MAC地址,通常在http连接的项目中,来区分唯一客户端. MAC:六组十六进制字符组成. 如:E0-3F-49-AB-DB-EB IP:四组八位的二进制字符组成. 如:10.6.62.244 /** ...

  3. C# 获取MAC地址

    /********************************************************************** * C# 获取MAC地址 * 说明: * 在C#中获取本 ...

  4. 分享:PHP获取MAC地址的实现代码

    原文地址:http://www.jbxue.com/article/12635.html发布:thatboy   来源:Net     [大 中 小] 分享一例php取得机器mac地址的代码,学习下p ...

  5. QT5下获取本机IP地址、计算机名、网络连接名、MAC地址、子网掩码、广播地址

    获取主机名称 /* * 名称:get_localmachine_name * 功能:获取本机机器名称 * 参数:no * 返回:QString */ QString CafesClient::get_ ...

  6. js 获取客户端mac地址

    js 获取客户端mac地址 javascript获取客户端网卡MAC地址和IP地址和计算机名 nodesj如何获得客户端的mac地址呢? 浏览器获取MAC地址 不限浏览器的mac地址取得的几种办法 I ...

  7. esp32使iOS 获取蓝牙外设的Mac地址

    最近在做一个需要上下位机的项目,我负责的任务下位机,使用的主控芯片是esp32.这个项目中有一项是需要手机扫描二维码然后连接作为esp32的蓝牙.二维码中包含了mac地址信息,在手机扫描周围设备的时候 ...

  8. Python - 获取本机IP地址、Mac地址

    Python - 获取本机IP地址.Mac地址 在python中获取ip地址和在php中有很大不同,在php中往往比较简单.那再python中怎么做呢? 直接看代码: # Python - 获取本机I ...

  9. 获取客户端Mac地址

    近期有个需求,需要获取客户端Mac地址作为白名单验证的依据.使用.net,B/S架构.先百度找了一些获取mac地址的方法, using System; using System.Collections ...

随机推荐

  1. 父组件向子组件传值时,值已经传过来却没有触发子组件的watch监听,解决~

    需求: 父组件像封装的子组件传值  (父组件属性传值,子组件props接受)   子组件接受后经过处理回显页面; 预想:子组件接受值 , 经过watch监听,在监听中处理数据,回显数据; 问题:子组件 ...

  2. python3之递归实例

    一.利用递归求: 1+2+3+4+5...+n的前n项和 def recursion_sum_1(n): #当n = 1:和为1 #否则,n的和等同于 n + (n -1) if n == 1: re ...

  3. Java 9 ← 2017,2019 Java → 13 ,都发生了什么?

    距离 2019 年结束,只剩下 35 天了.你做好准备迎接 2020 年了吗? 一到年底,人就特别容易陷入回忆和比较之中,比如说这几天, 的对比挑战就火了! 这个话题登上了微博的热搜榜,也刷爆了朋友圈 ...

  4. 一文彻底搞懂CAS实现原理 & 深入到CPU指令

    本文导读: 前言 如何保障线程安全 CAS原理剖析 CPU如何保证原子操作 解密CAS底层指令 小结 朋友,文章优先发布公众号,如果你愿意,可否扫文末二维码关注下? 前言 日常编码过程中,基本不会直接 ...

  5. iptables简单命令

    IPTables是基于Netfilter基本架构实现的一个可扩展的数据报高级管理系统或核外配置工具,利用table.chain.rule三级来存储数据报的各种规则.Netfilter-iptables ...

  6. 纵论WebAssembly,JS在性能逆境下召唤强援

    webassembly的作用 webassembly是一种底层的二进制数据格式和一套可以操作这种数据的JS接口的统称.我们可以认为webassembly的范畴里包含两部分 wasm: 一种体积小.加载 ...

  7. 使用python删除指定文件夹及子文件,保留多少

    python版本为:2.7 import os,time,shutil,datetime def rmdir(deldir,N): dellist=os.listdir(deldir) deldate ...

  8. 阿里架构师花近十年时间整理出来的Java核心知识pdf(Java岗)

    由于细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容! 整理了一份Java核心知识点.覆盖了JVM.锁.并发.Java反射.Spring原理.微服务.Zooke ...

  9. kubeadm配置高可用etcd集群

    操作系统为ubuntu18 kubernetes版本为v1.15.1 k8s默认在控制平面节点上的kubelet管理的静态pod中运行单个成员的etcd集群,但这不是高可用的方案. etcd高可用集群 ...

  10. python文件高级操作

    python文件高级操作和注意事项等等 文件过大保护 由于read是一次性读取文件所有的内容,如果文件100G,内存就会吃不消,所以推荐使用read(size)一次读取指定字节/字符(根据rb,或者r ...