我是靠谱客的博主 能干皮皮虾,最近开发中收集的这篇文章主要介绍C语言读取电脑识别码多努力就会有多特殊(neverforever)——仌,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

多努力就会有多特殊(neverforever)——仌

关于利用python读取电脑识别码的文章请关注我另一篇文章:
https://blog.csdn.net/weixin_44204327/article/details/85162826

目标

用C语言,读取电脑机器码,通过授权码,只允许软件运行在唯一电脑上,实现“一机一码”。
程序识别的机器码包括

  1. CPU序列号(ID)
  2. 本地连接 无线局域网 以太网的MAC
  3. 硬盘序列号(唯一)
  4. 主板序列号(唯一)

实现方法

软件安装后,运行软件时,通过电脑机器码的唯一性实现授权码的唯一性。

流程图

C代码函数功能简介

在这里插入图片描述

C程序代码

/*******************************  
 函数:
	1.mac:162387C5B7F7(以太、本地、局域)16:23:87:C5:B7:F7#34:23:87:C5:B7:F7#E0:DB:55:B5:9C:16
	2.harddisk硬盘序列号:3W0PKVLE
	3.harddisk和 mac合并为machine_code:3W0PKVLE16:23:87:C5:B7:F7
	4.machine_code去冒号:machine_code:3W0PKVLE162387C5B7F7
	5.获取machine_code奇数位:oddnumber:30KL328CBF
	6.奇数位加密: Key:996837194
	7.注册程序
	8.登录程序
  主函数:main()
********************************/
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <winsock2.h>
#include <Iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib, "Iphlpapi.lib")
#include <locale.h>
#include <tchar.h>
#include <windows.h>


// 1.1 MAC函数(以太网、本地、局域)
void byte2Hex(unsigned char bData, unsigned char hex[])
{
	int high = bData / 16, low = bData % 16;
	hex[0] = (high <10) ? ('0' + high) : ('A' + high - 10);
	hex[1] = (low <10) ? ('0' + low) : ('A' + low - 10);
}
// 1.2 获取本机MAC地址 
int getLocalMac(unsigned char *mac) 
{
	ULONG ulSize = 0;
	PIP_ADAPTER_INFO pInfo = NULL;
	int temp = 0;
	temp = GetAdaptersInfo(pInfo, &ulSize);//第一次调用,获取缓冲区大小
	pInfo = (PIP_ADAPTER_INFO)malloc(ulSize);
	temp = GetAdaptersInfo(pInfo, &ulSize);

	int iCount = 0;
	while (pInfo)//遍历每一张网卡
	{
		//  pInfo->Address 是MAC地址
		for (int i = 0; i<(int)pInfo->AddressLength; i++)
		{
			byte2Hex(pInfo->Address[i], &mac[iCount]);
			iCount += 2;
			if (i<(int)pInfo->AddressLength - 1)
			{
				mac[iCount++] = ':';
			}
			else
			{
				mac[iCount++] = '#';
			}
		}
		pInfo = pInfo->Next;
	}
	if (iCount >0)
	{
		mac[--iCount] = '';
		return iCount;
	}
	else return -1;
}

// 2.获取harddisk
// 2.1 harddisk函数
char * flipAndCodeBytes(const char * str, int pos, int flip, char * buf)
{
	int i;
	int j = 0;
	int k = 0;

	buf[0] = '';
	if (pos <= 0)
		return buf;

	if (!j)
	{
		char p = 0;
		// First try to gather all characters representing hex digits only.
		j = 1;
		k = 0;
		buf[k] = 0;
		for (i = pos; j && str[i] != ''; ++i)
		{
			char c = tolower(str[i]);

			if (isspace(c))
				c = '0';
			++p;
			buf[k] <<= 4;

			if (c >= '0' && c <= '9')
				buf[k] |= (unsigned char)(c - '0');
			else if (c >= 'a' && c <= 'f')
				buf[k] |= (unsigned char)(c - 'a' + 10);
			else
			{
				j = 0;
				break;
			}
			if (p == 2)
			{
				if (buf[k] != '' && !isprint(buf[k]))
				{
					j = 0;
					break;
				}
				++k;
				p = 0;
				buf[k] = 0;
			}
		}
	}

	if (!j)
	{
		// There are non-digit characters, gather them as is.
		j = 1;
		k = 0;
		for (i = pos; j && str[i] != ''; ++i)
		{
			char c = str[i];

			if (!isprint(c))
			{
				j = 0;
				break;
			}
			buf[k++] = c;
		}
	}

	if (!j)
	{
		// The characters are not there or are not printable.
		k = 0;
	}

	buf[k] = '';

	if (flip)
		// Flip adjacent characters
		for (j = 0; j < k; j += 2)
		{
			char t = buf[j];
			buf[j] = buf[j + 1];
			buf[j + 1] = t;
		}

	// Trim any beginning and end space
	i = j = -1;
	for (k = 0; buf[k] != ''; ++k)
	{
		if (!isspace(buf[k]))
		{
			if (i < 0)
				i = k;
			j = k;
		}
	}

	if ((i >= 0) && (j >= 0))
	{
		for (k = i; (k <= j) && (buf[k] != ''); ++k)
			buf[k - i] = buf[k];
		buf[k - i] = '';
	}
	return buf;
}
// 2.2 获取harddisk
ULONG GetHDSerial(PCHAR pszIDBuff, int nBuffLen, int nDriveID)
{
	HANDLE hPhysicalDrive = INVALID_HANDLE_VALUE;
	ULONG ulSerialLen = 0;
	__try
	{
		//  Try to get a handle to PhysicalDrive IOCTL, report failure
		//  and exit if can't.
		TCHAR szDriveName[32];
		wsprintf(szDriveName, TEXT("\\.\PhysicalDrive%d"), nDriveID);

		//  Windows NT, Windows 2000, Windows XP - admin rights not required
		hPhysicalDrive = CreateFile(szDriveName, 0,
			FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			OPEN_EXISTING, 0, NULL);
		if (hPhysicalDrive == INVALID_HANDLE_VALUE)
		{
			__leave;
		}
		STORAGE_PROPERTY_QUERY query;
		DWORD cbBytesReturned = 0;
		static char local_buffer[10000];

		memset((void *)&query, 0, sizeof(query));
		query.PropertyId = StorageDeviceProperty;
		query.QueryType = PropertyStandardQuery;

		memset(local_buffer, 0, sizeof(local_buffer));

		if (DeviceIoControl(hPhysicalDrive, IOCTL_STORAGE_QUERY_PROPERTY,
			&query,
			sizeof(query),
			&local_buffer[0],
			sizeof(local_buffer),
			&cbBytesReturned, NULL))
		{
			STORAGE_DEVICE_DESCRIPTOR * descrip = (STORAGE_DEVICE_DESCRIPTOR *)& local_buffer;
			char serialNumber[1000];

			flipAndCodeBytes(local_buffer,
				descrip->SerialNumberOffset,
				1, serialNumber);

			if (isalnum(serialNumber[0]))
			{
				ULONG ulSerialLenTemp = strnlen(serialNumber, nBuffLen - 1);
				memcpy(pszIDBuff, serialNumber, ulSerialLenTemp);
				pszIDBuff[ulSerialLenTemp] = NULL;
				ulSerialLen = ulSerialLenTemp;
				__leave;
			}

		}
	}
	__finally
	{
		if (hPhysicalDrive != INVALID_HANDLE_VALUE)
		{
			CloseHandle(hPhysicalDrive);
		}
		return ulSerialLen;
	}
}

char  machine_code[100];  // 机器码 串接的硬盘序列号和mac

// 3. 获取mac和harddisk 并串接
void GetAllHDSerial(void)
{

	// harddisk序列号输出
	const int MAX_IDE_DRIVES = 16;
	static char szBuff[0x100];
	for (int nDriveNum = 0; nDriveNum < MAX_IDE_DRIVES; nDriveNum++)
	{
		ULONG ulLen = GetHDSerial(szBuff, sizeof(szBuff), nDriveNum);

		/****************
		if (ulLen > 0)
		{
			_tprintf(TEXT("第%d块硬盘的序列号为:%hsn"), nDriveNum + 1, szBuff);
		}
		*****************/
		

	}

	// mac输出
	unsigned char address[1024];
	/*****************
	if (getLocalMac(address)>0)
	{
		printf("MAC:%sn", address);
	}
	******************/
	
	if (getLocalMac(address)<=0)
	{
		printf("invoke getMAC error!n");
	}


	// 串接字符串
	static char szBuff1[64];
	strncat(szBuff1, szBuff, 8);    // 取szBuff前8字串接到szBuff1末尾
	//printf("%sn", szBuff1);

	strncat(szBuff1, address, 17);  // 取mac前17位串接到szBuff1末尾
	//printf(szBuff);
	strcpy(machine_code, szBuff1);  // szBuff1赋值到machine_code机器码
	//printf(machine_code);

}

// 4. 去掉冒号
void del_chr(char *s, char ch)
{
	char *t = s; //目标指针先指向原串头
	while (*s != '') //遍历字符串s
	{
		if (*s != ch) //如果当前字符不是要删除的,则保存到目标串中
			*t++ = *s;
		s++; //检查下一个字符
	}
	*t = ''; //置目标串结束符。
}

// 5. 获取字符串奇数位
char oddnumber[30];
void odd(char a[30])
{
	int i, j = 0;
	
	for (i = 0; i < strlen(a); i += 2)
		oddnumber[j++] = a[i];
	oddnumber[j] = '';
	//printf("oddnumber:%sn", oddnumber);
}
// 6.1 奇数位加密
long StrToInt(char *s)  // 将一个字符串转化为整数
{
	long number = 0;
	while (*s != '')
	{
		number = number * 10 + *s - '0';
		s++;
	}
	return number;
}
// 6.2 奇数位加密
char Key[30];
void encrypt(char a[20])
{
	int num_Key = 0;
	num_Key = StrToInt(a);
	// 取正
	if (num_Key < 0)
	{
		num_Key = -num_Key;
	}

	_itoa(num_Key, Key, 10);  //把整数num_Key转成字符串str_Key
	printf("Key: %sn",Key);

}

// 7.注册程序
void regist(void)
{
	// 提示输入注册码
	char input_Key[30];
	char incout[] = "请输入注册码input_Key:";
	printf("%s", incout);
	scanf("%s", input_Key);
	//printf("please input code:%sn", code);

	// 获取机器码加密成注册码
	//char encode[] = "asd";
	//printf("got encode:%sn", encode);

	// 比较两个字符串是否一致
	if (strcmp(Key, input_Key) == 0)  // 若一致,新建打开data.txt ,写入注册码,运行程序
	{
		FILE *fp = fopen("data.txt", "w");
		fprintf(fp, "%s ", input_Key);
		fclose(fp); //关闭文件

		char succe[] = "运行应用成功2!";
		printf("%sn", succe);

	}
	else  //若不一致,提示不一致,并重新调用注册程序
	{
		char fail[] = "注册码不正确,请重新输入";
		printf("%sn", fail);
		regist();
	}
}

// 8.登录程序
void checkAuthored(void)
{
	// 2.1 获取机器码加密成注册码
	//char encode[] = "asd";
	//printf("got encode:%sn", encode);

	FILE *fp = fopen("data.txt", "r");
	char  filekey[30];
	// 2.2 若无注册文件,调用注册程序
	if ((fp = fopen("data.txt", "r")) == NULL)
	{
		printf("%s ", "have not registered");
		char fail[] = "请发送下列验证码到邮箱 863110979@qq.com 进行注册!";
		printf("%sn ", fail);
		printf("%sn ",oddnumber);
		regist();
		exit(1);
	}
	// 2.3 若文件为空,调用注册程序
	if (fgets(filekey, 30, fp) == NULL)
	{
		printf("%s", "file empty");
		char fail[] = "注册文件缺失!请重新输入注册码!若注册码忘记,请发送下列验证码到邮箱 863110979@qq.com 进行注册!";
		printf("%sn", fail);
		printf("%sn ", oddnumber);
		regist();
		exit(1);
	}
	// 2.4 若文件非空,取出注册码与新获得的注册码比较:一致:success;不一致:调用注册程序
	else
	{
		filekey[strlen(filekey) - 1] = '';   // 去除取出注册码的末尾字符
	//	int n, m;
	//	n = strlen(filekey);
	//	m = strlen(Key);
	//	printf("%d,%dn", n, m);
	//	printf("%sn", filekey); //输出注册文件内容
		if (strcmp(Key, filekey) == 0)
		{
			char succe[] = "运行应用成功1!";
			printf("%sn", succe);
			exit(1);
		}
		else
		{
			printf("%s", "file exist");
			char fail[] = "注册文件内容与注册码不一致!请重新输入注册码!若注册码忘记,请发送下列验证码到邮箱 863110979@qq.com 进行注册!";
			printf("%sn", fail);
			printf("%sn ", oddnumber);
			regist();
		}
	}


	fclose(fp); //关闭文件
}


// 主函数
int main(int argc, char* argv[])
{
	setlocale(LC_ALL, "chs");
	GetAllHDSerial();  // 获取mac与harddisk并拼接成机器码
	del_chr(machine_code, ':');  // 删除字符串内的冒号
	//printf("machine code:%sn", machine_code); // 整理好的机器码
	odd(machine_code); // oddnumber  机器码奇数位
	encrypt(oddnumber);// 加密后的注册码 key
	
	checkAuthored();   // 登录程序
	system("pause");


	return 0;
}

总结

  • C语言编译器使用的是Visual Studio 2017,调试期间出现过很多小错误,有些是关于编译器软件的设置的问题,自行百度。
  • 路径问题,文件存放位置需要注意
  • 代码中各小部分功能注释已经够详细了,希望能对你有所帮助。

最后

以上就是能干皮皮虾为你收集整理的C语言读取电脑识别码多努力就会有多特殊(neverforever)——仌的全部内容,希望文章能够帮你解决C语言读取电脑识别码多努力就会有多特殊(neverforever)——仌所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部