Java: 获取MAC网络地址
0. 背景
最近由于课程设计,需要使用MAC物理地址作为软件注册码的唯一标识,故成此博客!
从各个网络适配器的作用
→
\rightarrow
→ 确定哪一个MAC地址作为唯一标识。在此记录,与诸君分享。
1. 首先打开cmd
→
\rightarrow
→ ipconfig/all ,查看所有MAC地址:
2. 博主的ipconfig存在8个网络适配器,故而存在 8 个MAC物理地址。
其中每个网络适配器的含义如下:
Mac网卡地址解析:
Sangfor SSL VPN CS Support System VNIC
EasyConnect,远程连接VPN应用产生的虚拟网卡。
具备Mac网卡地址
Realtek PCIe GBE Family Controller
realtek公司生产的PCIe接口的千兆以太网家用控制器,即 有线网卡。
具备Mac网卡地址
VirtualBox Host-Only Ethernet Adapter
用于对 虚拟机 进行 通信 的适配器。
具备Mac网卡地址
Npcap Loopback Adapter
虚拟网卡,不涉及硬件,它被用于在网络连接不可用时,作为测试虚拟网络环境的工具。
此外,如果 网络适配器(network adapter) / 网络适配器驱动程序(network adapter driver) 发生冲突,则必须使用 Loopback适配器。
Java中的NetworkInterface中定义:
loopback interface that only supports communication between entities on this machine.
本地环回测试的MAC地址,全球所有的计算机相同!!!
具备Mac网卡地址
Microsoft Wi-Fi Direct Virtual Adapter
虚拟网卡,使用PC的便携式 热点(hotspot) 共享PC的互联网连接。
当PC连接无线网,并开启移动热点后,PC会向外发射信号给其他终端,其他终端检测到PC发射出的网络信号,并且可以连接PC发出的无线网络!
多用于移动设备投屏PC。
具备Mac网卡地址
Microsoft Wi-Fi Direct Virtual Adapter #2
Virual Wi-Fi是一种虚拟化网络适配器的技术,一旦被虚拟化,那么,即可将 1 个物理无线适配器转换为 2 个虚拟适配器。
具备Mac网卡地址
Intel® Dual Band Wireless-AC 3168
无线网卡。
具备Mac网卡地址
Bluetooth Device (Personal Area Network)
一种允许创建一个以太网(Ethernet network) 的技术,其允许计算机与移动设备等进行连接。
局域网(PAN)网卡。
具备Mac网卡地址
3. 了解了各网络适配器的MAC物理地址后,我们可以更加 自信 的编程了!
因为MAC地址数量很多,而虚拟网卡的MAC地址又可以后期修改,只有 无线网卡(Intel® Dual Band Wireless-AC 3168) 和 有限网卡(Realtek PCIe GBE Family Controller) 的MAC物理地址始终无法被改变并且绝大多数电脑都具备这两种网卡;
故,此处选择 无线网卡(Intel® Dual Band Wireless-AC 3168) 的MAC地址作为软件注册码的唯一标识。
ps:这里说明下,为什么不选择 Npcap Loopback Adapter 的MAC地址作为唯一标识的原因:
因为,全球所有的计算机的 Loopback Adapter 的 MAC地址 都为 02-00-4C-4F-4F-50;
而且,因为 MAC地址 位于计算机网络OSI参考模型的 数据链路层 中,其 作用 是 在网络中唯一标示一个网卡,并由此标识唯一计算机,这样,该计算机才能准确的与其他计算机通信;
然而, Loopback 的 作用 是用于 本地环回测试,不需要与其他计算机通信,因此其物理地址全球性一致,不具有唯一标识性。
ps: 感兴趣的小朋友可以cmd
→
\rightarrow
→ ipconfig/all 看下,是不是你的 Loopback 的MAC地址 是否与博主一致!😁
获取MAC地址程序如下:
import sun
.encryption
.constants
.Constants
;
import sun
.encryption
.domain
.Network
;
import java
.net
.InetAddress
;
import java
.net
.InterfaceAddress
;
import java
.net
.NetworkInterface
;
import java
.util
.ArrayList
;
import java
.util
.List
;
import java
.util
.Enumeration
;
public class NetworkUtil {
public static List
<Network> getMacAddresses() throws Exception
{
Enumeration
<NetworkInterface> en
= NetworkInterface
.getNetworkInterfaces();
StringBuilder sb
= new StringBuilder();
ArrayList
<String> networkNames
= new ArrayList<String>();
ArrayList
<Network> macList
= new ArrayList<Network>();
here
:
while (en
.hasMoreElements()) {
NetworkInterface iface
= en
.nextElement();
List
<InterfaceAddress> addrs
= iface
.getInterfaceAddresses();
for (InterfaceAddress addr
: addrs
) {
InetAddress ip
= addr
.getAddress();
NetworkInterface networkInterface
= NetworkInterface
.getByInetAddress(ip
);
if (networkInterface
== null
) {
continue;
}
String name
= networkInterface
.getName();
String displayName
= networkInterface
.getDisplayName();
byte[] mac
= networkInterface
.getHardwareAddress();
boolean virtual
= networkInterface
.isVirtual();
boolean up
= networkInterface
.isUp();
if (mac
== null
) {
continue;
}
sb
.delete(0, sb
.length());
for (int i
= 0; i
< mac
.length
; i
++) {
sb
.append(String
.format("%02X%s", mac
[i
], (i
< mac
.length
- 1) ? "-" : ""));
}
Network network
= new Network();
if (!networkNames
.contains(name
)) {
networkNames
.add(name
);
network
.setName(name
);
network
.setDisplayName(displayName
);
network
.setMac(sb
.toString());
network
.setVirtual(virtual
);
network
.setUp(up
);
macList
.add(network
);
}
if (networkNames
.contains(Constants
.WIRELESS
)) {
break here
;
}
}
}
return macList
;
}
public static String
getWirelessMacAddress() throws Exception
{
List
<Network> macs
= getMacAddresses();
for (Network mac
: macs
) {
if (mac
.getDisplayName().toLowerCase().contains(Constants
.WIRELESS
)) {
return mac
.getMac();
}
}
return null
;
}
public static void main(String
[] args
) throws Exception
{
String wirelessMac
= getWirelessMacAddress();
System
.out
.println(wirelessMac
);
}
}