介绍很多时候我们需要为一台Windows设备生成一个机器指纹来标识一台设备。当然标识设备最好的是与硬件相关的标识,应该硬件一般不会被改变。笔者参考了获取设备唯一标识这篇博客。笔者将使用下面几个字段进行机器指...

介绍
很多时候我们需要为一台Windows设备生成一个机器指纹来标识一台设备。当然标识设备最好的是与硬件相关的标识,应该硬件一般不会被改变。笔者参考了获取设备唯一标识这篇博客。笔者将使用下面几个字段进行机器指纹的生成。
- 主板UUID
wmic csproduct get UUID
唯一值,缺陷并不是所有的厂商都提供UUID(可以使用) - CPUID
wmic cpu get processorid
同一批次的PC,CPUID可能一样(可以使用) - BIOS序列号
wmic bios get serialnumber
刷了BIOS系统可能导致BIOS序列号变动(刷BIOS概率很小,可以使用) - 硬盘序列号
wmic diskdrive get serialnumber
多块硬盘,更换硬盘(概率较小,可以使用) - 网卡MAC地址
网卡更换,MAC地址易被更改 作为硬件不可靠(不建议使用)
代码
这里我们采用的策略是:主板UUID存在,就使用主板UUID生成机器指纹。主板UUID不存在,使用CPUID、BIOS序列号、硬盘序列号生成机器指纹。这里的散列算法用的标准库中自带。
#include <Windows.h>
#include <string>
#include <list>
#include <iostream>
#include <functional>
using namespace std;
#define BUFFER_SIZE 128
bool getDevcieInfo(char* cmd,list<string> &resultList) {
char buffer[BUFFER_SIZE];
bool ret = false;
FILE* pipe = _popen(cmd, "r"); //打开管道,并执行命令
if (!pipe)
return ret;
char *name[20] = {"UUID","ProcessorId","SerialNumber"};
int len0 = strlen(name[0]),len1 = strlen(name[1]),len2 = strlen(name[2]);
bool isOk = false;
while(!feof(pipe))
{
if(fgets(buffer, BUFFER_SIZE, pipe))
{
if( strncmp(name[0],buffer,len0) == 0
|| strncmp(name[1],buffer,len1) == 0
|| strncmp(name[2],buffer,len2) == 0 ) // 能够正确获取信息
{
isOk = true;
continue;
}
if( isOk == false
|| strcmp("\r\n",buffer) == 0 ) //去掉windows无用的空行
{
continue;
}
ret = true;
resultList.push_back(string(buffer));
}
}
_pclose(pipe); // 关闭管道
return ret;
}
string getDeviceFingerPrint(){
list<string> strList;
list<string>::iterator it;
hash<string> str_hash;
size_t num ;
char tmp[11] = {0};
// 主板UUID存在,就使用主板UUID生成机器指纹
if( getDevcieInfo("wmic csproduct get UUID",strList)
&& (*strList.begin()).compare("FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF\r\n") != 0)
{
//cout << *strList.begin();
//cout << str_hash(*strList.begin()) << endl;
num = str_hash(*strList.begin());
sprintf(tmp,"%u",num);
//cout << string(tmp) << endl;
return string(tmp);
}
// 主板UUID不存在,使用CPUID、BIOS序列号、硬盘序列号生成机器指纹
string otherStr("");
strList.clear();
if( getDevcieInfo("wmic cpu get processorid",strList) ){
otherStr.append( *strList.begin() );
}
strList.clear();
if( getDevcieInfo("wmic bios get serialnumber",strList) ){
otherStr.append( *strList.begin() );
}
strList.clear();
if( getDevcieInfo("wmic diskdrive get serialnumber",strList) ){
string allDiskNum("");
// 硬盘可能有多块
for(it = strList.begin();it != strList.end();it++)
{
allDiskNum.append(*it);
}
//cout << allDiskNum ;
//cout << str_hash(allDiskNum) << endl;
otherStr.append( *strList.begin() );
}
cout << str_hash(otherStr) << endl;
//memset(tmp,0,11);
num = str_hash(otherStr);
sprintf(tmp,"%u",num);
//cout << string(tmp) << endl;
return string(tmp);
}
void test()
{
string deviceFingerPrint = getDeviceFingerPrint();
cout << deviceFingerPrint << endl;
}
int main(int args,char* argv[])
{
test();
system("pause");
return 0;
}
沃梦达教程
本文标题为:C/C++:Windows获取电脑机器指纹


猜你喜欢
- 详解C语言中sizeof如何在自定义函数中正常工作 2023-04-09
- C语言手把手带你掌握带头双向循环链表 2023-04-03
- C语言qsort()函数的使用方法详解 2023-04-26
- Easyx实现扫雷游戏 2023-02-06
- c++ const 成员函数,返回一个 const 指针.但是返回的指针是什么类型的 const? 2022-10-11
- 我应该为我的项目使用相对包含路径,还是将包含目录放在包含路径上? 2022-10-30
- Qt计时器使用方法详解 2023-05-30
- C++ 数据结构超详细讲解顺序表 2023-03-25
- C语言详解float类型在内存中的存储方式 2023-03-27
- ubuntu下C/C++获取剩余内存 2023-09-18