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();
}
相关推荐
激流丶4 分钟前
【Kafka 实战】如何解决Kafka Topic数量过多带来的性能问题?
java·大数据·kafka·topic
Themberfue8 分钟前
Java多线程详解⑤(全程干货!!!)线程安全问题 || 锁 || synchronized
java·开发语言·线程·多线程·synchronized·
EricWang135819 分钟前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
September_ning19 分钟前
React.lazy() 懒加载
前端·react.js·前端框架
让学习成为一种生活方式25 分钟前
R包下载太慢安装中止的解决策略-R语言003
java·数据库·r语言
web行路人29 分钟前
React中类组件和函数组件的理解和区别
前端·javascript·react.js·前端框架
晨曦_子画30 分钟前
编程语言之战:AI 之后的 Kotlin 与 Java
android·java·开发语言·人工智能·kotlin
超雄代码狂1 小时前
ajax关于axios库的运用小案例
前端·javascript·ajax
南宫生1 小时前
贪心算法习题其三【力扣】【算法学习day.20】
java·数据结构·学习·算法·leetcode·贪心算法
长弓三石1 小时前
鸿蒙网络编程系列44-仓颉版HttpRequest上传文件示例
前端·网络·华为·harmonyos·鸿蒙