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();
}
相关推荐
kyriewen4 小时前
程序员连夜带团队跑路,省了23万:这AI太贵,真的用不起了
前端·javascript·openai
kyriewen4 小时前
你写的代码没有测试,就像出门不锁门——Jest + Testing Library 从入门到不慌
前端·单元测试·jest
zc.z4 小时前
JAVA实现:纯PCM格式音频转换成BASE64
java·音视频·pcm
mask哥5 小时前
力扣算法java实现汇总整理(上)
java·算法·leetcode
yuzhiboyouye5 小时前
web前端英语面试
前端·面试·状态模式
Aaswk6 小时前
Java Lambda 表达式与流处理
java·开发语言·python
是宇写的啊6 小时前
Spring AOP
java·spring
canonical_entropy6 小时前
下一代低代码渲染框架 nop-chaos-flux 的设计原则
前端·低代码·前端框架
万邦科技Lafite6 小时前
京东item_get接口实战案例:实时商品价格监控全流程解析
java·开发语言·数据库·python·开放api·淘宝开放平台
东方小月6 小时前
5分钟搞懂Harness Engineering(驾驭工程):从提示词到AI Agent的进化之路
前端·后端·架构