Ark Server API (ASA) - Wiki
Loading...
Searching...
No Matches
Blake3.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "Containers/StringFwd.h"
6#include "Containers/StringView.h"
7#include "Containers/UnrealString.h"
8#include "HAL/Platform.h"
9#include "HAL/PlatformString.h"
10#include "HAL/UnrealMemory.h"
11#include "Memory/MemoryFwd.h"
12#include "Memory/MemoryView.h"
13#include "Misc/AssertionMacros.h"
14#include "Serialization/Archive.h"
15#include "String/BytesToHex.h"
16#include "String/HexToBytes.h"
17#include "Templates/TypeCompatibleBytes.h"
18
19class FArchive;
20class FCompositeBuffer;
21template <typename CharType> class TStringBuilderBase;
22
23///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
24
25/** Stores a BLAKE3 hash. */
27{
28public:
29 using ByteArray = uint8[32];
30
31 /** Construct a zero hash. */
32 FBlake3Hash() = default;
33
34 /** Construct a hash from an array of 32 bytes. */
35 inline explicit FBlake3Hash(const ByteArray& Hash);
36
37 /** Construct a hash from a 64-character hex string. */
38 inline explicit FBlake3Hash(FAnsiStringView HexHash);
39 inline explicit FBlake3Hash(FWideStringView HexHash);
40 inline explicit FBlake3Hash(FUtf8StringView HexHash);
41
42 /** Construct a hash from a view of 32 bytes. */
43 inline static FBlake3Hash FromView(FMemoryView Hash);
44
45 /** Reset this to a zero hash. */
46 inline void Reset() { *this = FBlake3Hash(); }
47
48 /** Returns whether this is a zero hash. */
49 inline bool IsZero() const;
50
51 /** Returns a reference to the raw byte array for the hash. */
52 inline ByteArray& GetBytes() { return Hash; }
53 inline const ByteArray& GetBytes() const { return Hash; }
54
55 /** A zero hash. */
56 static const FBlake3Hash Zero;
57
58 inline bool operator==(const FBlake3Hash& B) const
59 {
60 return FMemory::Memcmp(GetBytes(), B.GetBytes(), sizeof(decltype(GetBytes()))) == 0;
61 }
62
63 inline bool operator!=(const FBlake3Hash& B) const
64 {
65 return FMemory::Memcmp(GetBytes(), B.GetBytes(), sizeof(decltype(GetBytes()))) != 0;
66 }
67
68 inline bool operator<(const FBlake3Hash& B) const
69 {
70 return FMemory::Memcmp(GetBytes(), B.GetBytes(), sizeof(decltype(GetBytes()))) < 0;
71 }
72
73 friend inline FArchive& operator<<(FArchive& Ar, FBlake3Hash& Value)
74 {
75 Ar.Serialize(Value.GetBytes(), sizeof(decltype(Value.GetBytes())));
76 return Ar;
77 }
78
79 friend inline uint32 GetTypeHash(const FBlake3Hash& Value)
80 {
81 return *reinterpret_cast<const uint32*>(Value.GetBytes());
82 }
83
84private:
85 alignas(uint32) ByteArray Hash{};
86};
87
88inline const FBlake3Hash FBlake3Hash::Zero;
89
90///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
91
92/** Calculates a BLAKE3 hash. */
94{
95public:
96 inline FBlake3() { Reset(); }
97
98 FBlake3(const FBlake3&) = delete;
99 FBlake3& operator=(const FBlake3&) = delete;
100
101 /** Reset to the default state in which no input has been written. */
102 void Reset();
103
104 /** Add the buffer as input to the hash. May be called any number of times. */
105 void Update(FMemoryView View);
106 void Update(const void* Data, uint64 Size);
107 void Update(const FCompositeBuffer& Buffer);
108
109 /**
110 * Finalize the hash of the input data.
111 *
112 * May be called any number of times, and more input may be added after.
113 */
115
116 /** Calculate the hash of the buffer. */
117 [[nodiscard]] static FBlake3Hash HashBuffer(FMemoryView View);
118 [[nodiscard]] static FBlake3Hash HashBuffer(const void* Data, uint64 Size);
119 [[nodiscard]] static FBlake3Hash HashBuffer(const FCompositeBuffer& Buffer);
120
121private:
123};
124
125///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
126
127inline FBlake3Hash::FBlake3Hash(const ByteArray& InHash)
128{
129 FMemory::Memcpy(Hash, InHash, sizeof(ByteArray));
130}
131
132inline FBlake3Hash::FBlake3Hash(const FAnsiStringView HexHash)
133{
134 check(HexHash.Len() == sizeof(ByteArray) * 2);
135 UE::String::HexToBytes(HexHash, Hash);
136}
137
138inline FBlake3Hash::FBlake3Hash(const FWideStringView HexHash)
139{
140 check(HexHash.Len() == sizeof(ByteArray) * 2);
141 UE::String::HexToBytes(HexHash, Hash);
142}
143
144inline FBlake3Hash::FBlake3Hash(const FUtf8StringView HexHash)
145{
146 check(HexHash.Len() == sizeof(ByteArray) * 2);
147 UE::String::HexToBytes(HexHash, Hash);
148}
149
150inline FBlake3Hash FBlake3Hash::FromView(const FMemoryView InHash)
151{
152 checkf(InHash.GetSize() == sizeof(ByteArray),
153 TEXT("FBlake3Hash cannot be constructed from a view of %" UINT64_FMT " bytes."), InHash.GetSize());
154 FBlake3Hash NewHash;
155 FMemory::Memcpy(NewHash.Hash, InHash.GetData(), sizeof(ByteArray));
156 return NewHash;
157}
158
159inline bool FBlake3Hash::IsZero() const
160{
161 using UInt32Array = uint32[8];
162 static_assert(sizeof(UInt32Array) == sizeof(ByteArray), "Invalid size for UInt32Array");
163 for (uint32 Value : reinterpret_cast<const UInt32Array&>(Hash))
164 {
165 if (Value != 0)
166 {
167 return false;
168 }
169 }
170 return true;
171}
172
173template <typename CharType>
174inline TStringBuilderBase<CharType>& operator<<(TStringBuilderBase<CharType>& Builder, const FBlake3Hash& Hash)
175{
176 UE::String::BytesToHexLower(Hash.GetBytes(), Builder);
177 return Builder;
178}
179
180/** Construct a hash from a 64-character hex string. */
181inline void LexFromString(FBlake3Hash& OutHash, const TCHAR* Buffer)
182{
183 OutHash = FBlake3Hash(Buffer);
184}
185
186/** Convert a hash to a 64-character hex string. */
187[[nodiscard]] FString LexToString(const FBlake3Hash& Hash);
#define check(expr)
#define checkf(expr, format,...)
void LexFromString(FBlake3Hash &OutHash, const TCHAR *Buffer)
Definition Blake3.h:181
FString LexToString(const FBlake3Hash &Hash)
virtual void Serialize(void *V, int64 Length)
Definition Archive.h:1569
FBlake3Hash Finalize() const
void Update(FMemoryView View)
TAlignedBytes< 1912, 8 > HasherBytes
Definition Blake3.h:122
static FBlake3Hash HashBuffer(const void *Data, uint64 Size)
void Update(const void *Data, uint64 Size)
static FBlake3Hash HashBuffer(const FCompositeBuffer &Buffer)
FBlake3()
Definition Blake3.h:96
void Update(const FCompositeBuffer &Buffer)
FBlake3(const FBlake3 &)=delete
void Reset()
static FBlake3Hash HashBuffer(FMemoryView View)
FBlake3 & operator=(const FBlake3 &)=delete
bool IsZero() const
Definition Blake3.h:159
const ByteArray & GetBytes() const
Definition Blake3.h:53
FBlake3Hash(const ByteArray &Hash)
Definition Blake3.h:127
static const FBlake3Hash Zero
Definition Blake3.h:56
bool operator!=(const FBlake3Hash &B) const
Definition Blake3.h:63
friend uint32 GetTypeHash(const FBlake3Hash &Value)
Definition Blake3.h:79
FBlake3Hash(FUtf8StringView HexHash)
Definition Blake3.h:144
FBlake3Hash(FAnsiStringView HexHash)
Definition Blake3.h:132
ByteArray & GetBytes()
Definition Blake3.h:52
FBlake3Hash()=default
static FBlake3Hash FromView(FMemoryView Hash)
Definition Blake3.h:150
ByteArray Hash
Definition Blake3.h:85
FBlake3Hash(FWideStringView HexHash)
Definition Blake3.h:138
void Reset()
Definition Blake3.h:46
bool operator<(const FBlake3Hash &B) const
Definition Blake3.h:68
bool operator==(const FBlake3Hash &B) const
Definition Blake3.h:58
static FORCEINLINE int32 Memcmp(const void *Buf1, const void *Buf2, SIZE_T Count)
static FORCEINLINE void * Memcpy(void *Dest, const void *Src, SIZE_T Count)