介绍很多时候我们需要为一台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++详细实现完整图书管理功能 2023-04-04
- 详解c# Emit技术 2023-03-25
- 如何C++使用模板特化功能 2023-03-05
- C语言基础全局变量与局部变量教程详解 2022-12-31
- C++使用easyX库实现三星环绕效果流程详解 2023-06-26
- C利用语言实现数据结构之队列 2022-11-22
- C语言 structural body结构体详解用法 2022-12-06
- C/C++编程中const的使用详解 2023-03-26
- 一文带你了解C++中的字符替换方法 2023-07-20
- C++中的atoi 函数简介 2023-01-05