UE5中一机一码功能
创建蓝图函数库
1、获取第一个有效的硬盘ID
// 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();
};
// 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地址
// 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();
};
// 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 adaptersuint32 RetVal = GetAdaptersInfo(IpAddresses, &OutBufferLength);if (RetVal == NO_ERROR){PIP_ADAPTER_INFO AdapterList = IpAddresses;// Walk the set of addresses to find the first valid MAC addresswhile (AdapterList){// If there is an address to readif (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 foundreturn Address;}AdapterList = AdapterList->Next;}}// If no valid MAC address is found, return an empty stringreturn FString("");
}
3、加密
// 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);};
// 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 UIbool UEncryptClass::EncryptStringWithAES(const FString& InputString, const FString& EncryptionKey, FString& OutEncryptedString)
{const unsigned char* iv = (const unsigned char*)"0123456789012345"; // 初始化向量(IV),需要与解密时一致int keylength = 128; // 加密密钥长度,可以是128、192或256EVP_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 stringFString 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、解密
// 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);
};
#include "DecryptClass.h"#define UI UI_ST
#include <openssl/ossl_typ.h>
#include <openssl/evp.h>
#undef UIbool 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 stringFString HexString;for (uint8 Byte : DecryptedData) {FString Hex = FString::Printf(TEXT("%02x"), Byte); // Convert byte to two-digit hex representationHexString += Hex;}OutDecryptedString = HexString;EVP_CIPHER_CTX_free(ctx);delete[] decryptedOutput;return true;
}
5、注册
// 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);};
// 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();
}