windows
命令行獲取CPU ID,可以用ShellExecute
wmic cpu get processorid
ProcessorId
BFEBFBFF000506E3
開源庫: 查詢CPU信息 . 包括ARM Mac windows
qemu
https://www.qemu.org/
讀取硬盤序列號
獲取CPU的ID
#include <intrin.h> // 所有Intrinsics函數
//64位程序,微軟不支持內嵌匯編指令
//https://blog.csdn.net/chlk118/article/details/51218964
//微軟推出了__cpuid和__cpuidex函數替代了匯編指令,獲取 __cpuid廠商,family,CPU名稱的代碼
同一個批次的CPU DeviceID 都是 BFEBFBFF000506E3
所以獲取意義不大!!!!!!!!
void GetCPUID()
{
char pvendor[16];
INT32 dwBuf[4];
__cpuid(dwBuf, 0);
*(INT32*)&pvendor[0] = dwBuf[1]; // ebx: 前四個字符
*(INT32*)&pvendor[4] = dwBuf[3]; // edx: 中間四個字符
*(INT32*)&pvendor[8] = dwBuf[2]; // ecx: 最后四個字符
pvendor[12] = '\0';
__cpuid(dwBuf, 0x1);
int family = (dwBuf[0] >> 8) & 0xf;
char pbrand[64];
__cpuid(dwBuf, 0x80000000);
if (dwBuf[0] < 0x80000004)
{
return;
}
__cpuid((INT32*)&pbrand[0], 0x80000002); // 前16個字符
__cpuid((INT32*)&pbrand[16], 0x80000003); // 中間16個字符
__cpuid((INT32*)&pbrand[32], 0x80000004); // 最后16個字符
pbrand[48] = '\0';
printf("get cpuid=");
printf(pvendor);
printf("\n");
printf(pbrand);
printf("\n");
__cpuidex(dwBuf, 1, 1);
char szTmp[33] = { NULL };
sprintf_s(szTmp, "%08X%08X", dwBuf[3], dwBuf[0]);
printf(szTmp);
printf("\n");
sprintf_s(szTmp, "%08X", family );
printf(szTmp);
}
輸出
get cpuid=GenuineIntel
Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz
BFEBFBFF000506E3
00000006
-----------------
//32位
//首先說明,CPU序列號並不是全球唯一的,以Intel為例,其不同型號的CPU序列號肯定不同,但不保證同型號的CPU序列號也各不相同,但據說P3后都是全球唯一的,沒有詳細考證。
//CPU序列號有一個好處就是非常難以修改,至少目前還沒聽說。將CPU ID 和MAC id 、硬盤id組合起來生成軟件序列號,可以大大增加序列號的安全性。(后兩者都可以通過軟件方法修改)。
string GetCPUID()
{
char cTemp[128];
string CPUID;
unsigned long s1, s2;
unsigned char vendor_id[] = "------------";
char sel;
sel = '1';
string VernderID;
string MyCpuID, CPUID1, CPUID2;
switch (sel)
{
case '1':
__asm {
xor eax, eax //eax=0:取Vendor信息
cpuid //取cpu id指令,可在Ring3級使用
mov dword ptr vendor_id, ebx
mov dword ptr vendor_id[+4], edx
mov dword ptr vendor_id[+8], ecx
}
VernderID = (char)vendor_id;
VernderID += "-";
__asm {
mov eax, 01h //eax=1:取CPU序列號
xor edx, edx
cpuid
mov s1, edx
mov s2, eax
}
sprintf_s(cTemp, "%08X%08X", s1, s2);
CPUID1 = cTemp;
__asm {
mov eax, 03h
xor ecx, ecx
xor edx, edx
cpuid
mov s1, edx
mov s2, ecx
}
sprintf_s(cTemp, "%08X%08X", s1, s2);
CPUID2 = cTemp;
break;
case '2':
{
__asm {
mov ecx, 119h
rdmsr
or eax, 00200000h
wrmsr
}
}
printf("CPU id is disabled.");
break;
}
MyCpuID = CPUID1 + CPUID2;
CPUID = MyCpuID;
printf(CPUID.c_str());
return CPUID;
}
輸出:
BFEBFBFF000506E3
string disk_id()
{
string id;
char Name[MAX_PATH];
DWORD serno;
DWORD length;
DWORD FileFlag;
char FileName[MAX_PATH];
BOOL Ret;
Ret = GetVolumeInformationA("c:\\", Name, MAX_PATH, &serno, &length, &FileFlag, FileName, MAX_PATH);
if (Ret)
{
id = std::to_string(serno);
}
printf("hard Disk id = ");
printf(id.c_str()); printf(" \n ");
return id;
}
輸出:
hard Disk id = 681865520
生成可在 x86 和 cpuid 上使用的 x64 指令。 本指令可查詢處理器,以獲取有關支持的功能和 CPU 類型的信息。
https://docs.microsoft.com/zh-cn/cpp/intrinsics/cpuid-cpuidex
// InstructionSet.cpp
// Compile by using: cl /EHsc /W4 InstructionSet.cpp
// processor: x86, x64
// Uses the __cpuid intrinsic to get information about
// CPU extended instruction set support.
#include <iostream>
#include <vector>
#include <bitset>
#include <array>
#include <string>
#include <intrin.h>
class InstructionSet
{
// forward declarations
class InstructionSet_Internal;
public:
// getters
static std::string Vendor(void) { return CPU_Rep.vendor_; }
static std::string Brand(void) { return CPU_Rep.brand_; }
static bool SSE3(void) { return CPU_Rep.f_1_ECX_[0]; }
static bool PCLMULQDQ(void) { return CPU_Rep.f_1_ECX_[1]; }
static bool MONITOR(void) { return CPU_Rep.f_1_ECX_[3]; }
static bool SSSE3(void) { return CPU_Rep.f_1_ECX_[9]; }
static bool FMA(void) { return CPU_Rep.f_1_ECX_[12]; }
static bool CMPXCHG16B(void) { return CPU_Rep.f_1_ECX_[13]; }
static bool SSE41(void) { return CPU_Rep.f_1_ECX_[19]; }
static bool SSE42(void) { return CPU_Rep.f_1_ECX_[20]; }
static bool SSE(void) { return CPU_Rep.f_1_EDX_[25]; }
static bool SSE2(void) { return CPU_Rep.f_1_EDX_[26]; }
static bool AVX2(void) { return CPU_Rep.f_7_EBX_[5]; }
static bool AVX512F(void) { return CPU_Rep.f_7_EBX_[16]; }
static bool AVX512PF(void) { return CPU_Rep.f_7_EBX_[26]; }
static bool AVX512ER(void) { return CPU_Rep.f_7_EBX_[27]; }
static bool AVX512CD(void) { return CPU_Rep.f_7_EBX_[28]; }
static bool SHA(void) { return CPU_Rep.f_7_EBX_[29]; }
static bool PREFETCHWT1(void) { return CPU_Rep.f_7_ECX_[0]; }
.........................
Output>>>>>>>
GenuineIntel
Intel(R) Core(TM) i5-2500 CPU @ 3.30GHz
AES supported
AVX supported
AVX2 not supported
AVX512CD not supported
AVX512ER not supported
AVX512F not supported
AVX512PF not supported
SHA not supported
SSE supported
SSE2 supported
SSE3 supported
SSE4.1 supported
SSE4.2 supported
SSE4a not supported
SSSE3 supported
dlib 也有封裝的庫,來測試指令集(各個平台的)
arm
唯一設備標識符適合:
● 用作序列號(例如 USB 字符串序列號或其它終端應用程序)
● 在對內部 Flash 進行編程前將唯一 ID 與軟件加密原語和協議結合使用時用作安全密鑰以提高 Flash 中代碼的安全性
● 激活安全自舉過程等
96 位的唯一設備標識符提供了一個對於任何設備和任何上下文都唯一的參考號碼。用戶永遠不能改變這些位。
96 位的唯一設備標識符也可以以單字節/半字/字等不同方式讀取,然后使用自定義算法連接起來。
基址:0x1FFF7A10
typedef struct
{ uint32_t id[3];
}ChipID;
ChipID Get_ChipID(void)
{
ChipID chipid = {0};
chipid.id[0] = *(__I uint32_t *)(0x1FFF7A10 + 0x00);
chipid.id[1] = *(__I uint32_t *)(0x1FFF7A10 + 0x04);
chipid.id[2] = *(__I uint32_t *)(0x1FFF7A10 + 0x08);
return chipid;
}
讀取STM32F207/40x的CPU唯一ID(Unique Device ID)號方法
產品唯一的身份標識的作用:
● 用來作為序列號(例如USB字符序列號或者其他的終端應用);
● 用來作為密碼,在編寫閃存時,將此唯一標識與軟件加解密算法結合使用,提高代碼在閃存存儲器內的安全性;
● 用來激活帶安全機制的自舉過程;
96位的產品唯一身份標識所提供的參考號碼對任意一個STM32微控制器,在任何情況下都是唯一的。用戶在何種情況下,都不能修改這個身份標識。按照用戶不同的用法,可以以字節(8位)為單位讀取,也可以以半字(16位)或者全字(32位)讀取。嘿嘿,要注意大端小端模式
* 函數名:Get_ChipID
* 描述 :獲取芯片ID
* 輸入 :無
* 輸出 :無
* 說明 :96位的ID是stm32唯一身份標識,可以以8bit、16bit、32bit讀取
提供了大端和小端兩種表示方法
void Get_ChipID(void)
{
#if 1
u32 ChipUniqueID[3];
地址從小到大,先放低字節,再放高字節:小端模式
地址從小到大,先放高字節,再放低字節:大端模式
ChipUniqueID[2] = *(__IO u32*)(0X1FFFF7E8); // 低字節
ChipUniqueID[1] = *(__IO u32 *)(0X1FFFF7EC); //
ChipUniqueID[0] = *(__IO u32 *)(0X1FFFF7F0); // 高字節
printf("######## 芯片的唯一ID為: X-X-X rn",ChipUniqueID[0],ChipUniqueID[1],ChipUniqueID[2]);
//此條語句輸出32位
#else //調整了大小端模式,與ISP下載軟件的一致
u8 temp[12];
u32 temp0,temp1,temp2;
temp0=*(__IO u32*)(0x1FFFF7E8); //產品唯一身份標識寄存器(96位)
temp1=*(__IO u32*)(0x1FFFF7EC);
temp2=*(__IO u32*)(0x1FFFF7F0);
temp[0] = (u8)(temp0 & 0x000000FF);
temp[1] = (u8)((temp0 & 0x0000FF00)>>8);
temp[2] = (u8)((temp0 & 0x00FF0000)>>16);
temp[3] = (u8)((temp0 & 0xFF000000)>>24);
temp[4] = (u8)(temp1 & 0x000000FF);
temp[5] = (u8)((temp1 & 0x0000FF00)>>8);
temp[6] = (u8)((temp1 & 0x00FF0000)>>16);
temp[7] = (u8)((temp1 & 0xFF000000)>>24);
temp[8] = (u8)(temp2 & 0x000000FF);
temp[9] = (u8)((temp2 & 0x0000FF00)>>8);
temp[10] = (u8)((temp2 & 0x00FF0000)>>16);
temp[11] = (u8)((temp2 & 0xFF000000)>>24);
printf("######## STM32芯片ID為: %.2X%.2X%.2X%.2X-%.2X%.2X%.2X%.2X-%.2X%.2X%.2X%.2X rn",
temp[0],temp[1],temp[2],temp[3],temp[4],temp[5],temp[6],temp[7],temp[8],temp[9],temp[10],temp [11]); //串口打印出芯片ID
#endif
}
* 函數名:Get_ChipInfo(void)
* 描述 :獲取芯片Flash 大小
* 輸入 :無
* 輸出 :無
* 說明 :
void Get_ChipInfo(void)
{
uint32_t ChipUniqueID[3];
u16 STM32_FLASH_SIZE;
ChipUniqueID[0] = *(__IO u32 *)(0X1FFFF7F0); // 高字節
ChipUniqueID[1] = *(__IO u32 *)(0X1FFFF7EC); //
ChipUniqueID[2] = *(__IO u32 *)(0X1FFFF7E8); // 低字節
STM32_FLASH_SIZE= *(u16*)(0x1FFFF7E0); //閃存容量寄存器
printf("rn########### 芯片的唯一ID為: %X-%X-%X n",
ChipUniqueID[0],ChipUniqueID[1],ChipUniqueID[2]);
printf("rn########### 芯片flash的容量為: %dK n", STM32_FLASH_SIZE);
printf("rn########### 燒錄日期: "__DATE__" - "__TIME__"n");
//輸出使用固件庫版本號
printf("rn########### 代碼固件庫版本: V %d.%d.%d n",__STM32F10X_STDPERIPH_VERSION_MAIN,__STM32F10X_STDPERIPH_VERSION_SUB1,__STM32F10X_STDPERIPH_VERSION_SUB2);
}