UE5中一机一码功能

创建蓝图函数库

1、获取第一个有效的硬盘ID

cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "GetDiskIDClass.generated.h"

/**
 * 
 */
UCLASS()
class OPENTEST_API UGetDiskIDClass : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
public:
	UFUNCTION(BlueprintCallable)
	static FString GetFirstDiskID();
};
cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.


#include "GetDiskIDClass.h"

#include <comutil.h>

FString UGetDiskIDClass::GetFirstDiskID()
{
	FString SerialNumber;

	for (int DriveNumber = 0; DriveNumber < 16; ++DriveNumber) {
		FString Drive = FString::Printf(TEXT("\\\\.\\PhysicalDrive%d"), DriveNumber);
		HANDLE hDevice = CreateFile(*Drive, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

		if (hDevice != INVALID_HANDLE_VALUE) {
			STORAGE_PROPERTY_QUERY storageQuery;
			memset(&storageQuery, 0, sizeof(storageQuery));
			storageQuery.PropertyId = StorageDeviceProperty;
			storageQuery.QueryType = PropertyStandardQuery;

			BYTE buffer[4096];
			DWORD bytesReturned = 0;

			if (DeviceIoControl(hDevice, IOCTL_STORAGE_QUERY_PROPERTY, &storageQuery, sizeof(storageQuery), &buffer, sizeof(buffer), &bytesReturned, NULL)) {
				STORAGE_DESCRIPTOR_HEADER* header = (STORAGE_DESCRIPTOR_HEADER*)buffer;
				if (header->Size > 0 && header->Size <= bytesReturned) {
					STORAGE_DEVICE_DESCRIPTOR* deviceDescriptor = (STORAGE_DEVICE_DESCRIPTOR*)buffer;

					if (deviceDescriptor->SerialNumberOffset > 0) {
						SerialNumber = FString(ANSI_TO_TCHAR((char*)deviceDescriptor + deviceDescriptor->SerialNumberOffset));
					}
				}
			}

			CloseHandle(hDevice);

			if (!SerialNumber.IsEmpty()) {
				return SerialNumber;
			}
		}
	}

	// 如果没有找到有效的硬盘ID,返回一个空字符串
	return FString("");
}

2、获取第一个有效的Mac地址

cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "GetFirstMacAddrClass.generated.h"

/**
 * 
 */
UCLASS()
class OPENTEST_API UGetFirstMacAddrClass : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
public:
	UFUNCTION(BlueprintCallable)
	static FString GetFirstMac();
};
cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.


#include "GetFirstMacAddrClass.h"

#include <Windows.h>
#include <IPHlpApi.h>

FString UGetFirstMacAddrClass::GetFirstMac()
{
	IP_ADAPTER_INFO IpAddresses[16];
	ULONG OutBufferLength = sizeof(IP_ADAPTER_INFO) * 16;

	// Read the adapters
	uint32 RetVal = GetAdaptersInfo(IpAddresses, &OutBufferLength);

	if (RetVal == NO_ERROR)
	{
		PIP_ADAPTER_INFO AdapterList = IpAddresses;

		// Walk the set of addresses to find the first valid MAC address
		while (AdapterList)
		{
			// If there is an address to read
			if (AdapterList->AddressLength > 0)
			{
				TArray<uint8> MacAddr;
				MacAddr.AddZeroed(AdapterList->AddressLength);
				FMemory::Memcpy(MacAddr.GetData(), AdapterList->Address, AdapterList->AddressLength);

				FString Address;
				for (TArray<uint8>::TConstIterator it(MacAddr); it; ++it)
				{
					Address += FString::Printf(TEXT("%02x"), *it);
				}

				// Return the first valid MAC address found
				return Address;
			}

			AdapterList = AdapterList->Next;
		}
	}

	// If no valid MAC address is found, return an empty string
	return FString("");
}

3、加密

cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "EncryptClass.generated.h"

/**
 * 
 */
UCLASS()
class OPENTEST_API UEncryptClass : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
public:
	UFUNCTION(BlueprintCallable)
	static bool EncryptStringWithAES(const FString& InputString, const FString& EncryptionKey, FString& OutEncryptedString);
	
	
	
};
cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.


 
#include "EncryptClass.h"

#define UI UI_ST
#include <openssl/ossl_typ.h>
#include <openssl/evp.h>
#undef UI


bool UEncryptClass::EncryptStringWithAES(const FString& InputString, const FString& EncryptionKey, FString& OutEncryptedString)
{
	const unsigned char* iv = (const unsigned char*)"0123456789012345"; // 初始化向量(IV),需要与解密时一致
	int keylength = 128; // 加密密钥长度,可以是128、192或256

	EVP_CIPHER_CTX* ctx;
	ctx = EVP_CIPHER_CTX_new();

	EVP_CIPHER_CTX_init(ctx);
	const EVP_CIPHER* cipherType = EVP_aes_128_cbc(); // 选择加密算法

	if (EVP_EncryptInit_ex(ctx, cipherType, NULL, (const unsigned char*)TCHAR_TO_UTF8(*EncryptionKey), iv) != 1) {
		// 初始化加密上下文失败
		return false;
	}

	int max_output_length = InputString.Len() + EVP_MAX_BLOCK_LENGTH; // 预估加密后的最大长度
	unsigned char* encryptedOutput = new unsigned char[max_output_length];
	int encryptedLength = 0;

	if (EVP_EncryptUpdate(ctx, encryptedOutput, &encryptedLength, (const unsigned char*)TCHAR_TO_UTF8(*InputString), InputString.Len()) != 1) {
		// 加密数据失败
		EVP_CIPHER_CTX_free(ctx);
		delete[] encryptedOutput;
		return false;
	}

	int finalEncryptedLength = 0;

	if (EVP_EncryptFinal_ex(ctx, encryptedOutput + encryptedLength, &finalEncryptedLength) != 1) {
		// 完成加密失败
		EVP_CIPHER_CTX_free(ctx);
		delete[] encryptedOutput;
		return false;
	}

	encryptedLength += finalEncryptedLength;

	// Convert encrypted data to hex string
	FString HexString;
	for (int i = 0; i < encryptedLength; ++i) {
		FString Hex = FString::Printf(TEXT("%02x"), encryptedOutput[i]);
		HexString += Hex;
	}

	OutEncryptedString = HexString;

	EVP_CIPHER_CTX_free(ctx);
	delete[] encryptedOutput;

	return true;
}

4、解密

cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "DecryptClass.generated.h"

/**
 * 
 */
UCLASS()
class OPENTEST_API UDecryptClass : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:
		
	UFUNCTION(BlueprintCallable)
	static bool DecryptStringWithAES(const FString& EncryptedString, const FString& EncryptionKey, FString& OutDecryptedString);
};
cpp 复制代码
#include "DecryptClass.h"

#define UI UI_ST
#include <openssl/ossl_typ.h>
#include <openssl/evp.h>
#undef UI

bool UMynewJMClass::DecryptStringWithAES(const FString& EncryptedString, const FString& EncryptionKey,
	FString& OutDecryptedString)
{
	const unsigned char* iv = (const unsigned char*)"0123456789012345"; // IV, 与加密时一致
	int keylength = 128; // 密钥长度,与加密时一致

	EVP_CIPHER_CTX* ctx;
	ctx = EVP_CIPHER_CTX_new();

	EVP_CIPHER_CTX_init(ctx);
	const EVP_CIPHER* cipherType = EVP_aes_128_cbc(); // 选择加密算法

	if (EVP_DecryptInit_ex(ctx, cipherType, NULL, (const unsigned char*)TCHAR_TO_UTF8(*EncryptionKey), iv) != 1) {
		// 初始化解密上下文失败
		return false;
	}

	int max_output_length = EncryptedString.Len() / 2; // 预估解密后的最大长度
	unsigned char* decryptedOutput = new unsigned char[max_output_length];
	int decryptedLength = 0;

	// 将十六进制字符串转换回原始加密数据
	TArray<uint8> EncryptedData;
	for (int i = 0; i < EncryptedString.Len(); i += 2) {
		FString ByteString = EncryptedString.Mid(i, 2);
		uint8 Byte = (uint8)FCString::Strtoi64(*ByteString, nullptr, 16);
		EncryptedData.Add(Byte);
	}

	if (EVP_DecryptUpdate(ctx, decryptedOutput, &decryptedLength, EncryptedData.GetData(), EncryptedData.Num()) != 1) {
		// 解密数据失败
		EVP_CIPHER_CTX_free(ctx);
		delete[] decryptedOutput;
		return false;
	}

	int finalDecryptedLength = 0;

	if (EVP_DecryptFinal_ex(ctx, decryptedOutput + decryptedLength, &finalDecryptedLength) != 1) {
		// 完成解密失败
		EVP_CIPHER_CTX_free(ctx);
		delete[] decryptedOutput;
		return false;
	}

	decryptedLength += finalDecryptedLength;

	// 将解密后的内容存储在 OutDecryptedData 中
	TArray<uint8> DecryptedData;
	DecryptedData.SetNumUninitialized(decryptedLength);
	FMemory::Memcpy(DecryptedData.GetData(), decryptedOutput, decryptedLength);

	// Convert the bytes to a hex string
	FString HexString;
	for (uint8 Byte : DecryptedData) {
		FString Hex = FString::Printf(TEXT("%02x"), Byte); // Convert byte to two-digit hex representation
		HexString += Hex;
	}

	OutDecryptedString = HexString;

	EVP_CIPHER_CTX_free(ctx);
	delete[] decryptedOutput;

	return true;
}

5、注册

cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "HexClass.generated.h"

/**
 * 
 */
UCLASS()
class OPENTEST_API UHexClass : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
public:
	UFUNCTION(BlueprintCallable)
	static FString HexStringToPlainText(const FString& HexString);

};
cpp 复制代码
// Fill out your copyright notice in the Description page of Project Settings.


#include "HexClass.h"

#include "GenericPlatform/GenericPlatformMisc.h"
#include "Misc/Guid.h"


FString UHexClass::HexStringToPlainText(const FString& HexString)
{
	FString PlainText;

	// 将十六进制字符串转换为原始文本
	for (int i = 0; i < HexString.Len(); i += 2)
	{
		FString ByteString = HexString.Mid(i, 2);
		int32 ByteValue = FCString::Strtoi(*ByteString, nullptr, 16);
		PlainText.AppendChar((TCHAR)ByteValue);
	}

	return PlainText;
}

FString UMyhuanyuanClass::GetMachineId()
{
	return  FPlatformMisc::GetMachineId().ToString();
}

TArray<uint8> UMyhuanyuanClass::GetAllMacAddress()
{
	
	
	return FPlatformMisc::GetMacAddress();
}
相关推荐
小林ixn8 分钟前
从 ??= 到 onKeyDown:一个 React 组件的“自我修养”
前端·javascript·react.js
REDcker34 分钟前
显示分辨率标准对照详解
前端·网络·分辨率·显示·屏幕
এ慕ོ冬℘゜1 小时前
前端实战:jQuery 多条件联合搜索(标题模糊查询 + 日历时间段筛选)
前端·javascript·jquery
武子康1 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端
大模型码小白1 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司2 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
一点一木2 小时前
从60首歌到1个网站:输入你的故事,还你一首歌
前端·github
爱笑的源码基地3 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
IT_陈寒3 小时前
Vue这个特性差点让我加班到凌晨,谁懂啊
前端·人工智能·后端
kyriewen3 小时前
我让AI改一个bug——它偷偷动了5个我没让它碰的地方
前端·javascript·ai编程