C/C++在程序中获取CPUID+网卡Mac的几种方法

56 篇文章 1 订阅
11 篇文章 0 订阅

注:此处的CPU是ARM架构的,但是获取网卡的代码是通用的。

直接上代码。
命令行获取到结果之后需要将16值字符串转换成整数:

int tolower(int c)
{
	if (c >= 'A' && c <= 'Z')
	{
		return c + 'a' - 'A';
	}
	else
	{
		return c;
	}
}

unsigned long htoul(char s[])
{
	int i;
	unsigned long n = 0;
	if (s[0] == '0' && (s[1]=='x' || s[1]=='X'))
	{
		i = 2;
	}
	else
	{
		i = 0;
	}
	for (; (s[i] >= '0' && s[i] <= '9') || (s[i] >= 'a' && s[i] <= 'z') || (s[i] >='A' && s[i] <= 'Z');++i)
	{
		if (tolower(s[i]) > '9')
		{
			n = 16 * n + (10 + tolower(s[i]) - 'a');
		}
		else
		{
			n = 16 * n + (tolower(s[i]) - '0');
		}
	}
	return n;
}

我这里用到三种方式,仅供参考:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <unistd.h>
#include <time.h>
#include <stdbool.h>

//cpuid
#include <asm/hwcap.h>
#include <sys/auxv.h>
//mac
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define GETCPUIDBYREG               //通过寄存器方式获取cpuid
#define GETCPUIDBYCPUREGSNUM       //通过命令行查看cpu序列号文件获取id
#define GETCPUIDBYCPUINFO          //执行命令行/proc/cpuinfo,获取cpu信息
unsigned long getCpuid_byCpuRegsNum()   //通过命令行查看cpu序列号文件
{
	FILE* fstream = NULL;
	char buf[1024];
	bzero(buf, sizeof(buf));

	if(NULL == (fstream = popen("cat /sys/devices/system/cpu/cpu0/regs/identification/midr_el1", "r")))
	{  
		perror("exec command failed!\n");
		return -1;
	}

	while(NULL != fgets(buf, sizeof(buf), fstream))
	{
		//printf("%s", buf+10);
	}
	pclose(fstream);
	//16进制字符串转整数
	unsigned long cpuid = htoul(buf+10);
    return cpuid;
}

unsigned long getCpuid_byCpuinfo()
{
	FILE* fstream = NULL;
	char buf[1024];
	bzero(buf, sizeof(buf));
    //执行命令行/proc/cpuinfo,获取cpu信息
	char cpuinfo[20];
	bzero(cpuinfo, sizeof(cpuinfo));

	char shellCmd[5][128] = 
	{
		"tail /proc/cpuinfo | grep \"CPU implementer\" | awk '{print $4}'",
		"tail /proc/cpuinfo | grep \"CPU variant\" | awk '{print $4}'",
		"tail /proc/cpuinfo | grep \"CPU variant\" | awk '{print $4}'",
		"tail /proc/cpuinfo | grep \"CPU part\" | awk '{print $4}'",
		"tail /proc/cpuinfo | grep \"CPU revision\" | awk '{print $4}'"
	};
	for(int i =0; i<5; i++ )
	{	
		if(NULL == (fstream = popen(shellCmd[i], "r")))
		{  
			perror("exec command failed!\n");
			return -1;
		}

		while(NULL != fgets(buf, sizeof(buf), fstream))
		{
			//printf("%s", buf);
		}
		if(buf[0] =='0' && (buf[1]=='x' || buf[1]=='X'))
			strncat(cpuinfo, buf+2, strlen(buf+2)-1);
		else
			strncat(cpuinfo, buf, strlen(buf)-1);
	}
	//printf("%s\n", cpuinfo);
	pclose(fstream);
	//16进制字符串转整数
	unsigned long cpuid = htoul(cpuinfo);
    return cpuid;
}

void cpuid(unsigned int op, unsigned int *buf)
{
	//printf("this Platform is ARM64\n");
	unsigned long __val;				
#ifdef GETCPUIDBYREG
	asm("mrs %0, MIDR_EL1" : "=r" (__val));  //寄存器方式获取cpuid
#elif defined GETCPUIDBYCPUREGSNUM
    __val = getCpuid_byCpuRegsNum();
#else
    __val = getCpuid_byCpuinfo();
#endif
	buf[0] = ((__val&0xffff)<< 16) | (__val >>16);     //将0x701f6633变成0x6633701f,因为之后的逻辑是取前16位,而6633所在cpu中的位置是比较唯一的。根据自己的情况看需不需要动这个cpuid
	buf[1] = ((__val&0xffff)<< 16) | (__val >>16);
	buf[2] = ((__val&0xffff)<< 16) | (__val >>16);
	buf[3] = ((__val&0xffff)<< 16) | (__val >>16);
	printf("0x%08lx\n", __val);	
	printf("buf[0-4]: %x %x %x %x\n", buf[0], buf[1], buf[2], buf[3]);
}

int get_mac(char szMac[10][50]/*char * mac, int len_limit*/)    //·μ???μê?êμ?êD?è?char * macμ?×?·???êy£?2?°üà?'\0'£?
{
	struct ifreq ifreq;
	struct ifaddrs *ifAddrStruct;   //为了获取网卡名
	int sock;
	static int num=0;
	if((sock=socket(AF_INET,SOCK_DGRAM,0))<0)
	{
		perror("socket");
		return -1;
	}
	unsigned char szText[256]={0};

	getifaddrs(&ifAddrStruct);
	int i = 0;
	while ((ifAddrStruct != NULL)) 
	{
		if (ifAddrStruct->ifa_addr->sa_family==AF_INET) 
		{
			//if(strcmp("lo", ifAddrStruct->ifa_name))   //若是localhost则跳过
			{
				printf("%s \n", ifAddrStruct->ifa_name);    //网卡名
				strcpy(ifreq.ifr_name,ifAddrStruct->ifa_name);
				if(ioctl (sock, SIOCGIFHWADDR, &ifreq) == -1 )//
				{
					//perror("ioctl");
					if(*szMac[i] == 0)
					{
						sprintf(szMac[i] , "%02X-%02X-%02X-%02X-%02X-%02X", 00, 00, 00, 00, 00, 00);
					}
					i++;
					num++;
					continue;
				}
				for(int k=0;k<6;k++)
				{
					szText[k]=(unsigned char)ifreq.ifr_hwaddr.sa_data[k];
				}
				//printf("%02x:%02x:%02x:%02x:%02x:%02x",szText[0],szText[1],szText[2],szText[3],szText[4],szText[5]);
				//printf("\n");
				sprintf(szMac[i], "%02X-%02X-%02X-%02X-%02X-%02X",szText[0],szText[1],szText[2],szText[3],szText[4],szText[5]);
				num++;	
				i++;  
			}     
		}
		ifAddrStruct=ifAddrStruct->ifa_next;
	}

	freeifaddrs(ifAddrStruct);
	close(sock);
	return num;
}

int main()
{
    printf("----getinfo start!----\n");
	char szMac[10][50]={0};
	int nRtn=get_mac(szMac);

	char   szCPUID[30]={0};
	unsigned int cpuinfo[4]={0};
	cpuid(1,cpuinfo);

	int i;
	for(i = 0; i < nRtn; i++)
	{
		if(strcmp(szMac[i], "00-00-00-00-00-00"))
		{
			memset(szCPUID, 0, sizeof(szCPUID));
			sprintf(szCPUID,"%s-%02X%02X",szMac[i],(cpuinfo[2]>>16)&0xFF,(cpuinfo[2]>>24)&0xFF);
             printf("%s\n",szCPUID);
			break;
		}
		else
		{
			memset(szCPUID, 0, sizeof(szCPUID));
			sprintf(szCPUID, "%s-%02X%02X", szMac[i], (cpuinfo[2]>>16)&0xFF,(cpuinfo[2]>>24)&0xFF);
		}
		printf("%s\n",szCPUID);
	}

    printf("----getinfo end!----\n");

    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值