我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么利用Node获取物理网卡mac地址

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么利用Node获取物理网卡mac地址

本篇内容介绍了“怎么利用Node获取物理网卡mac地址”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

在基于 Electron 的应用中,有一个业务需求是获取物理网卡的 Mac 地址以用于客户机唯一性识别。

刚接到需求时你可能会想,这还不简单,调用 Node.js 的 os 模块提供的 networkInterfaces API 就行了。

于是马上开干:

import { networkInterfaces } from 'os';

 function isZeroMac(mac) {
  return /^(0{1,2}[:-]){5}0{1,2}$/.test(mac);
}

function getMac(family = 'IPv4') {
    const nif = networkInterfaces();
    for (const list of Object.values(nif)) {
        const item = list.find(d => !d.internal && !isZeroMac(d.mac) && (!d.family ||d.family === family));
        if (item) return item.mac;
   }

   return '';
}

两分钟就写完了,测试一下返回值也与 ipconfig/ifconfig 打印的信息一致,满怀信心的提交代码完工。

测试同学当天验证了一下表示没什么问题,然而第二天却找上门了:同一台电脑今昨两天取到的值不一样。经过各种排查分析,最后才发现原来这位测试妹妹因疫情管控居家了,用着 VPN 远程接入办公网络干活呢。

原来开 VPN 的时候使用了虚拟网卡,此时你才发现事情并没有那么简单。实际上,在存在 VPN、虚拟机等场景下,都可能会使用到虚拟网卡。

1. 根据 networkInterfaces 返回值的字段值过滤

networkInterfaces 可以获取到所有网卡的基本信息,可根据 internalmac 等字段的值做一次过滤,得到有效的信息:

const isValid = (item) => item.internal === false && !isZeroMac(item.mac);

但是对于 VPN、虚拟机等存在虚拟网卡的场景下,仅根据该信息无法进行有效区分。

2. 根据虚拟网卡 Mac 特征过滤

如果能够得到虚拟网卡的特征,则可基于相关特征点进行识别与过滤。

基于某内部项目长达六年的实践积累以及参考 vscode 中类似的实现,我们得到了一个常见虚拟网卡默认 Mac 地址特征的列表,参考如下:

// see https://standards-oui.ieee.org/oui/oui.txt
const virtualMacPrefix = new Set([
  '00:05:69', // vmware1
  '00:0c:29', // vmware2
  '00:50:56', // vmware3
  '00:1c:14', // vmware
  '00:1c:42', // parallels1
  '02:00:4c', // Microsoft Loopback Adapter (微软回环网卡)
  '00:03:ff', // microsoft virtual pc
  '00:0f:4b', // virtual iron 4
  '00:16:3e', // red hat xen , oracle vm , xen source, novell xen
  '08:00:27', // virtualbox
]);

于是可以据此实现一个是否为虚拟网卡的判断方法 isVirtualMac

export function isMac(mac: string) {
  return /^([\da-f]{1,2}[:-]){5}([\da-f]{1,2})$/i.test(mac);
}

export function formatMac(mac: string) {
  return String(mac).trim().toLowerCase().replace(/-/g, ':');
}

export function isVirtualMac(mac: string) {
  return isMac(mac) && virtualMacPrefix.has(formatMac(mac).slice(0, 8));
}

据此可对 getMac 方法改进如下:

function getMac(family = 'IPv4') {
    const nif = networkInterfaces();
    for (const list of Object.values(nif)) {
        const item = list.find(d => !d.internal && !isZeroMac(d.mac) && (!d.family ||d.family === family) && !isVirtualMac(d.mac));
        if (item) return item.mac;
   }

   return '';
}

3. 根据描述关键字特征过滤

在 Windows 系统下,可以通过执行 ipconfig /allwmic nic get 命令得到所有网卡的详情,其中包含了描述信息。

基于实践经验分析,我们总结了一个常见虚拟网卡描述关键字的特征列表,参考如下:

const virtualDescList = ['virtual', ' vpn ', ' ssl ', 'tap-windows', 'hyper-v', 'km-test', 'microsoft loopback'];

若经过前述规则过滤之后仍然存在多个网卡信息,则可继续获取网卡详情,并基于 virtualDescList 列表以尝试进一步的过滤处理:

// 执行 wmic nic get 命令获取所有网卡详情
function getNetworkIFacesInfoByWmic() {
  // 略
}

if (hasMutiMac(list)) {
  const info = await getNetworkIFacesInfoByWmic();

  list = list.filter(item => {
    if (!info.config[item.mac]) return true;
    const desc = String(info.config[item.mac].desc).toLowerCase();
    return !virtualDescList.some(d => desc.includes(d));
  });
}

4. 按优先级规则排序

过滤方式会将视为无效的项排除,但是可能会因规则的误差而导致最后得到的列表为空。为了避免这种可能现象的出现,可以将过滤排除改为优先级排序方式,最后取列表第一项视为最优选项。

排序方法实现示例:


function ifacesSort(list: NetworkInterfaceInfo[]) {
  return list.sort((a, b) => {
    if (a.internal !== b.internal) return a.internal ? 1 : -1;
    if (isZeroMac(a.mac) !== isZeroMac(b.mac)) return isZeroMac(a.mac) ? 1 : -1;

    const isVirtualA = isVirtualMac(a.mac);
    const isVirtualB = isVirtualMac(b.mac);
    if (isVirtualA !== isVirtualB) return isVirtualA ? 1 : -1;

    if (a.family !== b.family) return a.family === 'IPv6' ? 1 : -1;
  });
}

于是最终的逻辑大致如下:

  • 获取全部网卡信息

  • 基于 iface 特征排序取得全部列表:en0 - mac, eth4 - linux, ethernet - windows 优先级更高

  • 基于 internal字段、虚拟网卡特征(mac)、family字段等进行排序

  • 对排序的结果进行基础过滤:internal=trueisZeroMac

  • 若过滤后列表多于1个,则基于虚拟网卡特征继续过滤

  • 若过滤结果仍多余1个,则基于描述特征继续过滤

  • 取最终结果的第一项作为最优选择

“怎么利用Node获取物理网卡mac地址”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么利用Node获取物理网卡mac地址

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Linux下怎么更改网卡的MAC物理地址

这篇文章主要讲解了“Linux下怎么更改网卡的MAC物理地址”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Linux下怎么更改网卡的MAC物理地址”吧!有些地方是把网络地址和网卡物理地址绑定
2023-06-10

怎么获得电脑网卡的物理地址

要获取电脑网卡的物理地址,可以按照以下步骤操作:1. 打开Windows系统的命令提示符。方法是按下Win + R键,然后输入"cmd",再按下Enter键。2. 在命令提示符窗口中,输入"ipconfig /all"命令,并按下Enter
2023-08-19

Shell脚本中怎么获取本地网卡IP和mac地址

这篇文章将为大家详细讲解有关Shell脚本中怎么获取本地网卡IP和mac地址,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。#/usr/bin/env bash# Name: get_netw
2023-06-09

VB.NET中怎么获取网卡地址

本篇文章给大家分享的是有关VB.NET中怎么获取网卡地址,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。VB.NET获取网卡地址步骤:1.在Visual Basic生成标准的EX
2023-06-17

客户端的IP地址与MAC地址怎么利用Java进行获取

这篇文章将为大家详细讲解有关客户端的IP地址与MAC地址怎么利用Java进行获取,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。1.获取客户端IP地址public String getIp(H
2023-05-31

怎么利用php获取ip地址

这篇文章主要介绍了怎么利用php获取ip地址,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。众所周知一般在计算机查询本机ip地址时,使用的是dos命令 win + r 调出do
2023-06-14

怎么用Python获取计算机名/ip地址/mac地址

这篇文章主要介绍“怎么用Python获取计算机名/ip地址/mac地址”,在日常操作中,相信很多人在怎么用Python获取计算机名/ip地址/mac地址问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用Py
2023-06-08

使用Python怎么获取计算机名,ip地址,mac地址

使用Python怎么获取计算机名,ip地址,mac地址?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。获取计算机名# 获取计算机名,常用的方法有三种,但最常用的是第一种impor
2023-06-15

怎么用BAT批处理获取外网IP地址

本篇内容介绍了“怎么用BAT批处理获取外网IP地址”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!代码如下:::===============
2023-06-08

怎么用Linux shell脚本获取外网IP地址

本篇内容介绍了“怎么用Linux shell脚本获取外网IP地址”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!基于Linux系统的获取外网I
2023-06-27

php局域网怎么获取所有用户的电脑IP和主机名、mac地址

本篇内容介绍了“php局域网怎么获取所有用户的电脑IP和主机名、mac地址”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!代码如下:
2023-06-20

利用java怎么样实现根据经纬度获取地址

这篇文章将为大家详细讲解有关利用java怎么样实现根据经纬度获取地址,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 java 根据经纬度获取地址实现代码实现代码:public class G
2023-05-31

怎么使用vbs脚本获取网卡MAC,CPUID,硬盘序列号

这篇文章给大家分享的是有关怎么使用vbs脚本获取网卡MAC,CPUID,硬盘序列号的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。这里先给大家分享一个分配静态ip地址的代码 Assign a Static IP A
2023-06-08

怎么利用在线代理ip获取网络资源

这篇文章主要介绍“怎么利用在线代理ip获取网络资源”,在日常操作中,相信很多人在怎么利用在线代理ip获取网络资源问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么利用在线代理ip获取网络资源”的疑惑有所帮助!
2023-06-20

怎么用BAT批处理判断IP地址并自动禁用启用网卡

本篇内容介绍了“怎么用BAT批处理判断IP地址并自动禁用启用网卡”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!某内网拨号软件设计问题,拨号后
2023-06-08

如何在Java项目中的链接地址怎么利用正则表达式获取

这篇文章给大家介绍如何在Java项目中的链接地址怎么利用正则表达式获取,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1、正则表达式中Matcher中find()方法的应用。2、String对象中的 replaceAll
2023-05-31

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录