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();
}
相关推荐
计算机徐师兄13 分钟前
Java基于SSM框架的无中介租房系统小程序【附源码、文档】
java·微信小程序·小程序·无中介租房系统小程序·java无中介租房系统小程序·无中介租房微信小程序
源码哥_博纳软云14 分钟前
JAVA智慧养老养老护理帮忙代办陪诊陪护小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
GDAL15 分钟前
vue3入门教程:ref能否完全替代reactive?
前端·javascript·vue.js
六卿15 分钟前
react防止页面崩溃
前端·react.js·前端框架
z千鑫41 分钟前
【前端】详解前端三大主流框架:React、Vue与Angular的比较与选择
前端·vue.js·react.js
m0_748256141 小时前
前端 MYTED单篇TED词汇学习功能优化
前端·学习
忒可君1 小时前
C# winform 报错:类型“System.Int32”的对象无法转换为类型“System.Int16”。
java·开发语言
斌斌_____2 小时前
Spring Boot 配置文件的加载顺序
java·spring boot·后端
路在脚下@2 小时前
Spring如何处理循环依赖
java·后端·spring
一个不秃头的 程序员2 小时前
代码加入SFTP JAVA ---(小白篇3)
java·python·github