mirror of
https://github.com/GOSTSec/poolserver
synced 2025-02-06 12:04:29 +00:00
Merkle tree hashing
This commit is contained in:
parent
377d216af1
commit
f2ec093448
@ -34,8 +34,31 @@ int Server::Run()
|
|||||||
sLog.Info(LOG_SERVER, "Server is starting...");
|
sLog.Info(LOG_SERVER, "Server is starting...");
|
||||||
|
|
||||||
//InitDatabase();
|
//InitDatabase();
|
||||||
|
std::vector<byte> test = Util::ASCIIToBin("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
|
||||||
|
sLog.Info(LOG_SERVER, "Hash: %s", Util::BinToASCII(Crypto::SHA256D(test)).c_str());
|
||||||
|
sLog.Info(LOG_SERVER, "RevHash: %s", Util::BinToASCII(Crypto::SHA256D(Util::Reverse(test))).c_str());
|
||||||
|
|
||||||
ByteBuffer buf(Util::ASCIIToBin("01000000010c432f4fb3e871a8bda638350b3d5c698cf431db8d6031b53e3fb5159e59d4a90000000000ffffffff0100f2052a010000001976a9143744841e13b90b4aca16fe793a7f88da3a23cc7188ac00000000"));
|
Bitcoin::Block block;
|
||||||
|
|
||||||
|
ByteBuffer buf(Util::ASCIIToBin("01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"));
|
||||||
|
Bitcoin::Transaction trans;
|
||||||
|
buf >> trans;
|
||||||
|
sLog.Info(LOG_SERVER, "Version: %u", trans.version);
|
||||||
|
sLog.Info(LOG_SERVER, "Inputs: %u", trans.in.size());
|
||||||
|
sLog.Info(LOG_SERVER, "PrevOut: %s", Util::BinToASCII(trans.in[0].prevout.hash).c_str());
|
||||||
|
sLog.Info(LOG_SERVER, "PrevOutn: %u", trans.in[0].prevout.n);
|
||||||
|
sLog.Info(LOG_SERVER, "ScriptSig: %s", Util::BinToASCII(trans.in[0].script.script).c_str());
|
||||||
|
sLog.Info(LOG_SERVER, "Inn: %u", trans.in[0].n);
|
||||||
|
sLog.Info(LOG_SERVER, "Outputs: %u", trans.out.size());
|
||||||
|
sLog.Info(LOG_SERVER, "Value: %i", trans.out[0].value);
|
||||||
|
sLog.Info(LOG_SERVER, "PubSig: %s", Util::BinToASCII(trans.out[0].scriptPubKey.script).c_str());
|
||||||
|
sLog.Info(LOG_SERVER, "LockTime: %u", trans.lockTime);
|
||||||
|
block.tx.resize(1);
|
||||||
|
block.tx[0] = trans;
|
||||||
|
block.BuildMerkleTree();
|
||||||
|
sLog.Info(LOG_SERVER, "Hash: %s", Util::BinToASCII(block.merkleRootHash).c_str());
|
||||||
|
|
||||||
|
/*ByteBuffer buf(Util::ASCIIToBin("01000000010c432f4fb3e871a8bda638350b3d5c698cf431db8d6031b53e3fb5159e59d4a90000000000ffffffff0100f2052a010000001976a9143744841e13b90b4aca16fe793a7f88da3a23cc7188ac00000000"));
|
||||||
|
|
||||||
Bitcoin::Transaction trans;
|
Bitcoin::Transaction trans;
|
||||||
buf >> trans;
|
buf >> trans;
|
||||||
@ -43,7 +66,7 @@ int Server::Run()
|
|||||||
ByteBuffer buf2;
|
ByteBuffer buf2;
|
||||||
buf2 << trans;
|
buf2 << trans;
|
||||||
|
|
||||||
sLog.Info(LOG_SERVER, "Trans: %s", Util::BinToASCII(buf2.vec).c_str());
|
sLog.Info(LOG_SERVER, "Trans: %s", Util::BinToASCII(buf2.vec).c_str());*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,9 @@
|
|||||||
#include "Transaction.h"
|
#include "Transaction.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
namespace Bitcoin
|
namespace Bitcoin
|
||||||
{
|
{
|
||||||
@ -22,12 +25,45 @@ namespace Bitcoin
|
|||||||
class Block : public BlockHeader
|
class Block : public BlockHeader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// Serializable
|
||||||
std::vector<Transaction> tx;
|
std::vector<Transaction> tx;
|
||||||
|
|
||||||
std::vector<byte> GenerateMerkle()
|
// Other data
|
||||||
|
std::vector<std::vector<byte> > merkleTree;
|
||||||
|
|
||||||
|
void BuildMerkleTree()
|
||||||
{
|
{
|
||||||
|
merkleTree.clear();
|
||||||
|
|
||||||
|
uint64 branches = 1;
|
||||||
|
uint32 levels = 0;
|
||||||
|
while (branches < tx.size()) {
|
||||||
|
branches *= 2;
|
||||||
|
++levels;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add transactions
|
||||||
|
for (uint64 i = 0; i < branches; ++i)
|
||||||
|
merkleTree.push_back(tx[std::min(i, tx.size()-1)].GetHash());
|
||||||
|
|
||||||
|
uint32 merkleIndex = 0;
|
||||||
|
for (uint32 level = levels; level > 0; --level)
|
||||||
|
{
|
||||||
|
// Decrease before calculating because bottom level is transactions
|
||||||
|
branches /= 2;
|
||||||
|
|
||||||
|
for (uint32 branch = 0; branch < branches; ++branch)
|
||||||
|
merkleTree.push_back(Crypto::SHA256D(Util::Join(merkleTree[merkleIndex++], merkleTree[merkleIndex++])));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Last hash is merkle root
|
||||||
|
merkleRootHash = merkleTree[merkleTree.size()-1];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Block Serialization (Implementation in Serialization.cpp)
|
||||||
|
ByteBuffer& operator<<(ByteBuffer& a, Block& b);
|
||||||
|
ByteBuffer& operator>>(ByteBuffer& a, Block& b);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -63,6 +63,7 @@ namespace Bitcoin
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Script Serialization (Implementation in Serialization.cpp)
|
||||||
ByteBuffer& operator<<(ByteBuffer& a, Script& b);
|
ByteBuffer& operator<<(ByteBuffer& a, Script& b);
|
||||||
ByteBuffer& operator>>(ByteBuffer& a, Script& b);
|
ByteBuffer& operator>>(ByteBuffer& a, Script& b);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "VarInt.h"
|
#include "VarInt.h"
|
||||||
#include "Script.h"
|
#include "Script.h"
|
||||||
#include "Transaction.h"
|
#include "Transaction.h"
|
||||||
|
#include "Block.h"
|
||||||
|
|
||||||
using namespace Bitcoin;
|
using namespace Bitcoin;
|
||||||
|
|
||||||
@ -8,16 +9,16 @@ using namespace Bitcoin;
|
|||||||
ByteBuffer& Bitcoin::operator<<(ByteBuffer& a, VarInt& b)
|
ByteBuffer& Bitcoin::operator<<(ByteBuffer& a, VarInt& b)
|
||||||
{
|
{
|
||||||
if (b.value < 0xfd) {
|
if (b.value < 0xfd) {
|
||||||
a.Append(b.value, 1);
|
a.Append<uint8>(b.value);
|
||||||
} else if (b.value <= 0xffff) {
|
} else if (b.value <= 0xffff) {
|
||||||
a.Append(0xfd, 1);
|
a.Append<uint8>(0xfd);
|
||||||
a.Append(b.value, 2);
|
a.Append<uint16>(b.value);
|
||||||
} else if (b.value <= 0xffffffff) {
|
} else if (b.value <= 0xffffffff) {
|
||||||
a.Append(0xfe, 1);
|
a.Append<uint8>(0xfe);
|
||||||
a.Append(b.value, 4);
|
a.Append<uint32>(b.value);
|
||||||
} else {
|
} else {
|
||||||
a.Append(0xff, 1);
|
a.Append<uint8>(0xff);
|
||||||
a.Append(b.value, 8);
|
a.Append<uint64>(b.value);
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
@ -61,7 +62,7 @@ ByteBuffer& Bitcoin::operator<<(ByteBuffer& a, OutPoint& b)
|
|||||||
ByteBuffer& Bitcoin::operator>>(ByteBuffer& a, OutPoint& b)
|
ByteBuffer& Bitcoin::operator>>(ByteBuffer& a, OutPoint& b)
|
||||||
{
|
{
|
||||||
b.hash = a.ReadBytes(32);
|
b.hash = a.ReadBytes(32);
|
||||||
b.n = a.Read<uint32>();
|
a >> b.n;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ ByteBuffer& Bitcoin::operator>>(ByteBuffer& a, TxIn& b)
|
|||||||
{
|
{
|
||||||
a >> b.prevout;
|
a >> b.prevout;
|
||||||
a >> b.script;
|
a >> b.script;
|
||||||
b.n = a.Read<uint32>();
|
a >> b.n;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ ByteBuffer& Bitcoin::operator<<(ByteBuffer& a, TxOut& b)
|
|||||||
}
|
}
|
||||||
ByteBuffer& Bitcoin::operator>>(ByteBuffer& a, TxOut& b)
|
ByteBuffer& Bitcoin::operator>>(ByteBuffer& a, TxOut& b)
|
||||||
{
|
{
|
||||||
b.value = a.Read<uint64>();
|
a >> b.value;
|
||||||
a >> b.scriptPubKey;
|
a >> b.scriptPubKey;
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
@ -103,28 +104,29 @@ ByteBuffer& Bitcoin::operator<<(ByteBuffer& a, Transaction& b)
|
|||||||
// Inputs
|
// Inputs
|
||||||
VarInt insize(b.in.size());
|
VarInt insize(b.in.size());
|
||||||
a << insize;
|
a << insize;
|
||||||
for (uint32 i = 0; i < b.in.size(); ++i)
|
for (uint64 i = 0; i < insize; ++i)
|
||||||
a << b.in[i];
|
a << b.in[i];
|
||||||
|
|
||||||
// Outputs
|
// Outputs
|
||||||
VarInt outsize(b.out.size());
|
VarInt outsize(b.out.size());
|
||||||
a << outsize;
|
a << outsize;
|
||||||
for (uint32 i = 0; i < b.out.size(); ++i)
|
for (uint64 i = 0; i < outsize; ++i)
|
||||||
a << b.out[i];
|
a << b.out[i];
|
||||||
|
|
||||||
a << b.lockTime;
|
a << b.lockTime;
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
ByteBuffer& Bitcoin::operator>>(ByteBuffer& a, Transaction& b)
|
ByteBuffer& Bitcoin::operator>>(ByteBuffer& a, Transaction& b)
|
||||||
{
|
{
|
||||||
b.version = a.Read<uint32>();
|
a >> b.version;
|
||||||
|
|
||||||
// Inputs
|
// Inputs
|
||||||
VarInt insize;
|
VarInt insize;
|
||||||
a >> insize;
|
a >> insize;
|
||||||
|
|
||||||
b.in.resize(insize);
|
b.in.resize(insize);
|
||||||
for (uint32 i = 0; i < insize; ++i)
|
for (uint64 i = 0; i < insize; ++i)
|
||||||
a >> b.in[i];
|
a >> b.in[i];
|
||||||
|
|
||||||
// Outputs
|
// Outputs
|
||||||
@ -132,9 +134,47 @@ ByteBuffer& Bitcoin::operator>>(ByteBuffer& a, Transaction& b)
|
|||||||
a >> outsize;
|
a >> outsize;
|
||||||
|
|
||||||
b.out.resize(outsize);
|
b.out.resize(outsize);
|
||||||
for (uint32 i = 0; i < outsize; ++i)
|
for (uint64 i = 0; i < outsize; ++i)
|
||||||
a >> b.out[i];
|
a >> b.out[i];
|
||||||
|
|
||||||
b.lockTime = a.Read<uint32>();
|
a >> b.lockTime;
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block
|
||||||
|
ByteBuffer& Bitcoin::operator<<(ByteBuffer& a, Block& b)
|
||||||
|
{
|
||||||
|
a << b.version;
|
||||||
|
a << b.prevBlockHash;
|
||||||
|
a << b.merkleRootHash;
|
||||||
|
a << b.time;
|
||||||
|
a << b.bits;
|
||||||
|
a << b.nonce;
|
||||||
|
|
||||||
|
// Serialize transactions
|
||||||
|
VarInt txcount(b.tx.size());
|
||||||
|
a << txcount;
|
||||||
|
for (uint64 i = 0; i < txcount; ++i)
|
||||||
|
a << b.tx[i];
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
ByteBuffer& Bitcoin::operator>>(ByteBuffer& a, Block& b)
|
||||||
|
{
|
||||||
|
a >> b.version;
|
||||||
|
b.prevBlockHash = a.ReadBytes(32);
|
||||||
|
b.merkleRootHash = a.ReadBytes(32);
|
||||||
|
a >> b.time;
|
||||||
|
a >> b.bits;
|
||||||
|
a >> b.nonce;
|
||||||
|
|
||||||
|
VarInt txcount;
|
||||||
|
a >> txcount;
|
||||||
|
|
||||||
|
b.tx.resize(txcount);
|
||||||
|
for (uint64 i = 0; i < txcount; ++i)
|
||||||
|
a >> b.tx[i];
|
||||||
|
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
12
src/server/shared/Bitcoin/Transaction.cpp
Normal file
12
src/server/shared/Bitcoin/Transaction.cpp
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#include "Transaction.h"
|
||||||
|
#include "Util.h"
|
||||||
|
|
||||||
|
namespace Bitcoin
|
||||||
|
{
|
||||||
|
std::vector<byte> Transaction::GetHash()
|
||||||
|
{
|
||||||
|
ByteBuffer buf;
|
||||||
|
buf << *this;
|
||||||
|
return Crypto::SHA256D(buf.Bytes());
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@
|
|||||||
#include "ByteBuffer.h"
|
#include "ByteBuffer.h"
|
||||||
#include "VarInt.h"
|
#include "VarInt.h"
|
||||||
#include "Script.h"
|
#include "Script.h"
|
||||||
|
#include "Crypto.h"
|
||||||
|
|
||||||
namespace Bitcoin
|
namespace Bitcoin
|
||||||
{
|
{
|
||||||
@ -49,6 +50,8 @@ namespace Bitcoin
|
|||||||
std::vector<TxIn> in;
|
std::vector<TxIn> in;
|
||||||
std::vector<TxOut> out;
|
std::vector<TxOut> out;
|
||||||
uint32 lockTime;
|
uint32 lockTime;
|
||||||
|
|
||||||
|
std::vector<byte> GetHash();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Transaction Serialization (Implementation in Serialization.cpp)
|
// Transaction Serialization (Implementation in Serialization.cpp)
|
||||||
|
@ -18,6 +18,7 @@ namespace Bitcoin
|
|||||||
friend ByteBuffer& operator<<(ByteBuffer& a, VarInt& b);
|
friend ByteBuffer& operator<<(ByteBuffer& a, VarInt& b);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// VarInt Serialization (Implementation in Serialization.cpp)
|
||||||
ByteBuffer& operator<<(ByteBuffer& a, VarInt& b);
|
ByteBuffer& operator<<(ByteBuffer& a, VarInt& b);
|
||||||
ByteBuffer& operator>>(ByteBuffer& a, VarInt& b);
|
ByteBuffer& operator>>(ByteBuffer& a, VarInt& b);
|
||||||
}
|
}
|
||||||
|
@ -20,50 +20,25 @@ public:
|
|||||||
Append(b);
|
Append(b);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
ByteBuffer& operator<<(uint8& b)
|
|
||||||
|
template<typename T>
|
||||||
|
ByteBuffer& operator<<(T& b)
|
||||||
{
|
{
|
||||||
Append(b, 1);
|
Append<T>(b);
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
ByteBuffer& operator<<(uint16& b)
|
|
||||||
{
|
|
||||||
Append(b, 2);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
ByteBuffer& operator<<(uint32& b)
|
|
||||||
{
|
|
||||||
Append(b, 4);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
ByteBuffer& operator<<(uint64& b)
|
|
||||||
{
|
|
||||||
Append(b, 8);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
ByteBuffer& operator<<(int8& b)
|
|
||||||
{
|
|
||||||
Append(b, 1);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
ByteBuffer& operator<<(int16& b)
|
|
||||||
{
|
|
||||||
Append(b, 2);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
ByteBuffer& operator<<(int32& b)
|
|
||||||
{
|
|
||||||
Append(b, 4);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
ByteBuffer& operator<<(int64& b)
|
|
||||||
{
|
|
||||||
Append(b, 8);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Append(uint64 data, size_t size)
|
template<typename T>
|
||||||
|
ByteBuffer& operator>>(T& b)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < size; i++)
|
b = Read<T>();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void Append(T data)
|
||||||
|
{
|
||||||
|
for (uint8 i = 0; i < sizeof(T); ++i)
|
||||||
vec.push_back(data >> (i * 8));
|
vec.push_back(data >> (i * 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,14 +65,19 @@ public:
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
T data = 0;
|
T data = 0;
|
||||||
for (uint32 i = 0; i < size; ++i)
|
for (uint64 i = 0; i < size; ++i)
|
||||||
data += vec[pointer+i]<<(i*8);
|
data += (T)vec[pointer+i]<<(i*8);
|
||||||
|
|
||||||
pointer += size;
|
pointer += size;
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<byte> Bytes()
|
||||||
|
{
|
||||||
|
return vec;
|
||||||
|
}
|
||||||
|
|
||||||
uint64 pointer;
|
uint64 pointer;
|
||||||
std::vector<byte> vec;
|
std::vector<byte> vec;
|
||||||
};
|
};
|
||||||
|
25
src/server/shared/Crypto.cpp
Normal file
25
src/server/shared/Crypto.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "Crypto.h"
|
||||||
|
|
||||||
|
namespace Crypto
|
||||||
|
{
|
||||||
|
std::vector<byte> SHA256(std::vector<byte> data)
|
||||||
|
{
|
||||||
|
std::vector<byte> hash;
|
||||||
|
hash.resize(SHA256_DIGEST_LENGTH);
|
||||||
|
SHA256_CTX sha256;
|
||||||
|
SHA256_Init(&sha256);
|
||||||
|
SHA256_Update(&sha256, &data[0], data.size());
|
||||||
|
SHA256_Final(&hash[0], &sha256);
|
||||||
|
return std::vector<byte>(hash.begin(), hash.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<byte> SHA256(std::string data)
|
||||||
|
{
|
||||||
|
return SHA256(std::vector<byte>(data.begin(), data.end()));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<byte> SHA256D(std::vector<byte> data)
|
||||||
|
{
|
||||||
|
return SHA256(SHA256(data));
|
||||||
|
}
|
||||||
|
}
|
@ -9,26 +9,9 @@
|
|||||||
|
|
||||||
namespace Crypto
|
namespace Crypto
|
||||||
{
|
{
|
||||||
std::vector<byte> SHA256(std::vector<byte> data)
|
std::vector<byte> SHA256(std::vector<byte> data);
|
||||||
{
|
std::vector<byte> SHA256(std::string data);
|
||||||
std::vector<byte> hash;
|
std::vector<byte> SHA256D(std::vector<byte> data);
|
||||||
hash.resize(SHA256_DIGEST_LENGTH);
|
|
||||||
SHA256_CTX sha256;
|
|
||||||
SHA256_Init(&sha256);
|
|
||||||
SHA256_Update(&sha256, &data[0], data.size());
|
|
||||||
SHA256_Final(&hash[0], &sha256);
|
|
||||||
return std::vector<byte>(hash.begin(), hash.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<byte> SHA256(std::string data)
|
|
||||||
{
|
|
||||||
return SHA256(std::vector<byte>(data.begin(), data.end()));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<byte> SHA256D(std::vector<byte> data)
|
|
||||||
{
|
|
||||||
return SHA256(SHA256(data));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -85,3 +85,10 @@ std::vector<byte> Util::Reverse(std::vector<byte> data)
|
|||||||
std::reverse(out.begin(), out.end());
|
std::reverse(out.begin(), out.end());
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<byte> Util::Join(std::vector<byte> v1, std::vector<byte> v2)
|
||||||
|
{
|
||||||
|
std::vector<byte> v3 = v1;
|
||||||
|
v3.insert(v3.end(), v2.begin(), v2.end());
|
||||||
|
return v3;
|
||||||
|
}
|
||||||
|
@ -108,6 +108,7 @@ namespace Util
|
|||||||
std::vector<byte> ASCIIToBin(std::string str);
|
std::vector<byte> ASCIIToBin(std::string str);
|
||||||
std::string BinToASCII(std::vector<byte> data);
|
std::string BinToASCII(std::vector<byte> data);
|
||||||
std::vector<byte> Reverse(std::vector<byte> data);
|
std::vector<byte> Reverse(std::vector<byte> data);
|
||||||
|
std::vector<byte> Join(std::vector<byte> v1, std::vector<byte> v2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user