添加项目文件。
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
#include "JsonUnicodeWriter.h"
|
||||
|
||||
JsonUnicodeWriter::JsonUnicodeWriter()
|
||||
{
|
||||
jswb["emitUTF8"] = true;
|
||||
jswb["indentation"] = "";
|
||||
jswb["precisionType"] = "decimal";
|
||||
jswb["commentStyle"] = "None";
|
||||
}
|
||||
|
||||
string JsonUnicodeWriter::write(Json::Value root)
|
||||
{
|
||||
unique_ptr<Json::StreamWriter>writer(jswb.newStreamWriter());
|
||||
ostringstream oss;
|
||||
writer->write(root, &oss);
|
||||
return oss.str();
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <json/json.h>
|
||||
|
||||
using std::string;
|
||||
using std::unique_ptr;
|
||||
using std::ostringstream;
|
||||
|
||||
class JsonUnicodeWriter
|
||||
{
|
||||
private:
|
||||
Json::StreamWriterBuilder jswb;
|
||||
public:
|
||||
JsonUnicodeWriter();
|
||||
public:
|
||||
string write(Json::Value root);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
#include "Public.h"
|
||||
#include "JsonUnicodeWriter.h"
|
||||
|
||||
namespace uns
|
||||
{
|
||||
HashResult::HashResult()
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
|
||||
HashResult::HashResult(std::string res)
|
||||
{
|
||||
result = res;
|
||||
success = true;
|
||||
last_error = "";
|
||||
}
|
||||
|
||||
HashResult::HashResult(const HashResult& obj)
|
||||
{
|
||||
result = obj.result;
|
||||
success = obj.success;
|
||||
last_error = obj.last_error;
|
||||
}
|
||||
|
||||
HashResult::HashResult(bool succ, std::string res, std::string err)
|
||||
{
|
||||
result = res;
|
||||
success = succ;
|
||||
if (!success)
|
||||
last_error = err;
|
||||
}
|
||||
|
||||
HashResult HashResult::Faliure(std::string str)
|
||||
{
|
||||
return HashResult(false, "", str);
|
||||
}
|
||||
|
||||
HashResult HashResult::Success(std::string str)
|
||||
{
|
||||
return HashResult(true, str, "");
|
||||
}
|
||||
|
||||
std::string HashResult::GetResult()
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string HashResult::GetLastError()
|
||||
{
|
||||
return last_error;
|
||||
}
|
||||
|
||||
std::string HashResult::EncodeJsonString(bool unicode, bool styled)
|
||||
{
|
||||
if (unicode)
|
||||
{
|
||||
JsonUnicodeWriter writer;
|
||||
return writer.write(*this);
|
||||
}
|
||||
try
|
||||
{
|
||||
Json::Writer* writer = nullptr;
|
||||
if (styled)
|
||||
writer = new Json::StyledWriter();
|
||||
else
|
||||
writer = new Json::FastWriter();
|
||||
std::string result = writer->write(*this);
|
||||
delete writer;
|
||||
return result;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return "{\"Success\":false,\"Result\":\"\",\"LastError\":\"STD C++ Error Catched\"}";
|
||||
}
|
||||
}
|
||||
|
||||
HashResult::operator bool()
|
||||
{
|
||||
return success;
|
||||
}
|
||||
|
||||
HashResult::operator std::string()
|
||||
{
|
||||
return (success ? result : last_error);
|
||||
}
|
||||
|
||||
HashResult::operator Json::Value()
|
||||
{
|
||||
Json::Value root;
|
||||
root["Result"] = result;
|
||||
root["Success"] = success;
|
||||
root["LastError"] = last_error;
|
||||
return root;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,94 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include <rhash.h>
|
||||
#include <cstdint>
|
||||
#include <json/json.h>
|
||||
#pragma warning(disable : 4251)
|
||||
#pragma warning(disable : 4996)
|
||||
|
||||
#ifdef UOHASH_EXPORTS
|
||||
#define UOHASH_DLL_API __declspec(dllexport)
|
||||
#else
|
||||
#define UOHASH_DLL_API __declspec(dllimport)
|
||||
#ifdef _DEBUG
|
||||
#pragma comment(lib, "../x64/Debug/UOHashd.lib")
|
||||
#else
|
||||
#pragma comment(lib, "../x64/Release/UOHash.lib")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace uns
|
||||
{
|
||||
enum class UOHASH_DLL_API HashID : std::int64_t
|
||||
{
|
||||
CRC32 = RHASH_CRC32,
|
||||
MD4 = RHASH_MD4,
|
||||
MD5 = RHASH_MD5,
|
||||
SHA1 = RHASH_SHA1,
|
||||
TIGER = RHASH_TIGER,
|
||||
TTH = RHASH_TTH,
|
||||
BTIH = RHASH_BTIH,
|
||||
ED2K = RHASH_ED2K,
|
||||
AICH = RHASH_AICH,
|
||||
WHIRLPOOL = RHASH_WHIRLPOOL,
|
||||
RIPEMD160 = RHASH_RIPEMD160,
|
||||
GOST94 = RHASH_GOST94,
|
||||
GOST94_CRYPTOPRO = RHASH_GOST94_CRYPTOPRO,
|
||||
HAS160 = RHASH_HAS160,
|
||||
GOST12_256 = RHASH_GOST12_256,
|
||||
GOST12_512 = RHASH_GOST12_512,
|
||||
SHA224 = RHASH_SHA224,
|
||||
SHA256 = RHASH_SHA256,
|
||||
SHA384 = RHASH_SHA384,
|
||||
SHA512 = RHASH_SHA512,
|
||||
EDONR256 = RHASH_EDONR256,
|
||||
EDONR512 = RHASH_EDONR512,
|
||||
SHA3_224 = RHASH_SHA3_224,
|
||||
SHA3_256 = RHASH_SHA3_256,
|
||||
SHA3_384 = RHASH_SHA3_384,
|
||||
SHA3_512 = RHASH_SHA3_512,
|
||||
CRC32C = RHASH_CRC32C,
|
||||
SNEFRU128 = RHASH_SNEFRU128,
|
||||
SNEFRU256 = RHASH_SNEFRU256,
|
||||
BLAKE2S = RHASH_BLAKE2S,
|
||||
BLAKE2B = RHASH_BLAKE2B, //0x40000000
|
||||
__RHASH_MAX = 0b01111111111111111111111111111111,
|
||||
SHAKE128 = 0x80000000,
|
||||
SHAKE256 = 0x100000000,
|
||||
BASE16 = 0x200000000,
|
||||
BASE32 = 0x400000000,
|
||||
BASE32_HEX = 0x800000000,
|
||||
BASE36 = 0x1000000000,
|
||||
BASE58 = 0x2000000000,
|
||||
BASE62 = 0x4000000000,
|
||||
BASE64 = 0x8000000000,
|
||||
BASE64_URL = 0x10000000000,
|
||||
BASE85 = 0x20000000000,
|
||||
BASE91 = 0x40000000000,
|
||||
URL = 0x80000000000
|
||||
};
|
||||
|
||||
class UOHASH_DLL_API HashResult
|
||||
{
|
||||
private:
|
||||
bool success;
|
||||
std::string result;
|
||||
std::string last_error;
|
||||
public:
|
||||
HashResult();
|
||||
HashResult(std::string res);
|
||||
HashResult(const HashResult& obj);
|
||||
HashResult(bool succ, std::string res, std::string err);
|
||||
public:
|
||||
static HashResult Faliure(std::string str);
|
||||
static HashResult Success(std::string str);
|
||||
public:
|
||||
std::string GetResult();
|
||||
std::string GetLastError();
|
||||
std::string EncodeJsonString(bool unicode = false, bool styled = false);
|
||||
public:
|
||||
operator bool();
|
||||
operator std::string();
|
||||
operator Json::Value();
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,394 @@
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include "UOHash.h"
|
||||
#include <stdarg.h>
|
||||
#include "URLCodec.h"
|
||||
#include "basecodec.hpp"
|
||||
#include "base36_codec.hpp"
|
||||
#include <rhash_torrent.h>
|
||||
#include <cryptopp/shake.h>
|
||||
#include <cryptopp/base32.h>
|
||||
#include <cryptopp/base64.h>
|
||||
#include <cryptopp/basecode.h>
|
||||
|
||||
namespace uns
|
||||
{
|
||||
bool UOHash::FileExist(std::string file)
|
||||
{
|
||||
std::fstream fs(file, std::ios::in);
|
||||
if (fs.is_open())
|
||||
{
|
||||
fs.close();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
int UOHash::CalculateHashSize(HashID HashID)
|
||||
{
|
||||
switch (HashID)
|
||||
{
|
||||
case HashID::CRC32: return 8;
|
||||
case HashID::MD4: return 32;
|
||||
case HashID::MD5: return 32;
|
||||
case HashID::SHA1: return 40;
|
||||
case HashID::TIGER: return 48;
|
||||
case HashID::TTH: return 39;
|
||||
case HashID::BTIH: return 40;
|
||||
case HashID::ED2K: return 32;
|
||||
case HashID::AICH: return 32;
|
||||
case HashID::WHIRLPOOL: return 128;
|
||||
case HashID::RIPEMD160: return 40;
|
||||
case HashID::GOST94: return 64;
|
||||
case HashID::GOST94_CRYPTOPRO: return 64;
|
||||
case HashID::HAS160: return 40;
|
||||
case HashID::GOST12_256: return 64;
|
||||
case HashID::GOST12_512: return 128;
|
||||
case HashID::SHA224: return 56;
|
||||
case HashID::SHA256: return 64;
|
||||
case HashID::SHA384: return 96;
|
||||
case HashID::SHA512: return 128;
|
||||
case HashID::EDONR256: return 64;
|
||||
case HashID::EDONR512: return 128;
|
||||
case HashID::SHA3_224: return 56;
|
||||
case HashID::SHA3_256: return 64;
|
||||
case HashID::SHA3_384: return 96;
|
||||
case HashID::SHA3_512: return 128;
|
||||
case HashID::CRC32C: return 8;
|
||||
case HashID::SNEFRU128: return 32;
|
||||
case HashID::SNEFRU256: return 64;
|
||||
case HashID::BLAKE2S: return 64;
|
||||
case HashID::BLAKE2B: return 128;
|
||||
default: return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string UOHash::RemoveWhiteChar(std::string str)
|
||||
{
|
||||
std::string ret;
|
||||
for (auto& ele : str)
|
||||
if ((ele != ' ') && (ele != '\n') && (ele != '\t'))
|
||||
ret.push_back(ele);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int UOHash::CalculateHashExSize(HashID HashID, int output_bits)
|
||||
{
|
||||
if (HashID == HashID::SHAKE128)
|
||||
return 64;
|
||||
else if (HashID == HashID::SHAKE256)
|
||||
return 128;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
rhash_print_sum_flags UOHash::PickOutputType(HashID HashID)
|
||||
{
|
||||
if ((HashID == HashID::TTH) || (HashID == HashID::AICH))
|
||||
return RHPR_BASE32;
|
||||
else
|
||||
return RHPR_HEX;
|
||||
}
|
||||
|
||||
HashResult UOHash::DecodeString(HashID HashID, std::string Source)
|
||||
{
|
||||
if (HashID < HashID::BASE16)
|
||||
return HashResult::Faliure(INVALID_HASH_FUNCTION);
|
||||
else
|
||||
{
|
||||
switch (HashID)
|
||||
{
|
||||
case HashID::BASE16:
|
||||
{
|
||||
std::string output;
|
||||
if (basecodec::decodeBase16(Source, output))
|
||||
return HashResult::Success(output);
|
||||
else
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
}
|
||||
case HashID::BASE32:
|
||||
{
|
||||
std::string ret = "";
|
||||
CryptoPP::StringSource source(Source, true, new CryptoPP::Base32Decoder(new CryptoPP::StringSink(ret)));
|
||||
if (ret == "")
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
else
|
||||
return HashResult::Success(ret);
|
||||
}
|
||||
case HashID::BASE32_HEX:
|
||||
{
|
||||
std::string ret = "";
|
||||
CryptoPP::StringSource source(Source, true, new CryptoPP::Base32HexDecoder(new CryptoPP::StringSink(ret)));
|
||||
if (ret == "")
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
else
|
||||
return HashResult::Success(ret);
|
||||
}
|
||||
case HashID::BASE36:
|
||||
{
|
||||
std::string out;
|
||||
if (basecodec::decodeBase36ToDecimalString(Source, out))
|
||||
return HashResult::Success(out);
|
||||
else
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
}
|
||||
case HashID::BASE62:
|
||||
{
|
||||
std::string out;
|
||||
if (basecodec::decodeBase62(Source, out))
|
||||
return HashResult::Success(out);
|
||||
else
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
}
|
||||
case HashID::BASE58:
|
||||
{
|
||||
std::string out;
|
||||
if (basecodec::decodeBase58(Source, out))
|
||||
return HashResult::Success(out);
|
||||
else
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
}
|
||||
case HashID::BASE64:
|
||||
{
|
||||
std::string ret = "";
|
||||
CryptoPP::StringSource source(Source, true, new CryptoPP::Base64Decoder(new CryptoPP::StringSink(ret)));
|
||||
if (ret == "")
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
else
|
||||
return HashResult::Success(ret);
|
||||
}
|
||||
case HashID::BASE64_URL:
|
||||
{
|
||||
std::string ret = "";
|
||||
CryptoPP::StringSource source(Source, true, new CryptoPP::Base64URLDecoder(new CryptoPP::StringSink(ret)));
|
||||
if (ret == "")
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
else
|
||||
return HashResult::Success(ret);
|
||||
}
|
||||
case HashID::BASE85:
|
||||
{
|
||||
std::string output;
|
||||
if (basecodec::decodeBase85(Source, output))
|
||||
return HashResult::Success(output);
|
||||
else
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
}
|
||||
case HashID::BASE91:
|
||||
{
|
||||
std::string output;
|
||||
if (basecodec::decodeBase91(Source, output))
|
||||
return HashResult::Success(output);
|
||||
else
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
}
|
||||
case HashID::URL:
|
||||
{
|
||||
std::string out;
|
||||
if (urlcodec::url_decode(Source, out))
|
||||
return HashResult::Success(out);
|
||||
else
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
}
|
||||
default:
|
||||
return HashResult::Faliure(INVALID_HASH_FUNCTION);
|
||||
}
|
||||
return HashResult::Faliure(INVALID_HASH_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
HashResult UOHash::HashString(HashID HashID, std::string Source, int ex_output_bits)
|
||||
{
|
||||
if (HashID >= HashID::__RHASH_MAX)
|
||||
{
|
||||
switch (HashID)
|
||||
{
|
||||
case HashID::SHAKE128:
|
||||
{
|
||||
if (ex_output_bits <= 0)
|
||||
return HashResult::Faliure(INVALID_HASHEX_ARGUMENT);
|
||||
CryptoPP::SHAKE128 shake128(ex_output_bits);
|
||||
int hash_size = CalculateHashExSize(HashID, ex_output_bits);
|
||||
unsigned char* recv = new unsigned char[ex_output_bits + 10];
|
||||
char* hashstr = new char[hash_size + 10];
|
||||
memset(recv, 0, (ex_output_bits + 10));
|
||||
memset(hashstr, 0, (hash_size + 10));
|
||||
shake128.CalculateDigest(recv, (const unsigned char*)Source.data(), Source.size());
|
||||
rhash_print_bytes(hashstr, recv, (hash_size / 2), (RHPR_HEX | RHPR_UPPERCASE));
|
||||
std::string str(hashstr);
|
||||
delete[] recv;
|
||||
recv = nullptr;
|
||||
delete[] hashstr;
|
||||
hashstr = nullptr;
|
||||
return HashResult::Success(RemoveWhiteChar(str));
|
||||
}
|
||||
case HashID::SHAKE256:
|
||||
{
|
||||
if (ex_output_bits <= 0)
|
||||
return HashResult::Faliure(INVALID_HASHEX_ARGUMENT);
|
||||
CryptoPP::SHAKE256 shake256(ex_output_bits);
|
||||
int hash_size = CalculateHashExSize(HashID, ex_output_bits);
|
||||
unsigned char* recv = new unsigned char[ex_output_bits + 10];
|
||||
char* hashstr = new char[hash_size + 10];
|
||||
memset(recv, 0, (ex_output_bits + 10));
|
||||
memset(hashstr, 0, (hash_size + 10));
|
||||
shake256.CalculateDigest(recv, (const unsigned char*)Source.data(), Source.size());
|
||||
rhash_print_bytes(hashstr, recv, (hash_size / 2), (RHPR_HEX | RHPR_UPPERCASE));
|
||||
std::string str(hashstr);
|
||||
delete[] recv;
|
||||
recv = nullptr;
|
||||
delete[] hashstr;
|
||||
hashstr = nullptr;
|
||||
return HashResult::Success(RemoveWhiteChar(str));
|
||||
}
|
||||
case HashID::BASE16:
|
||||
return HashResult::Success(basecodec::encodeBase16(Source));
|
||||
case HashID::BASE32:
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string ret = "";
|
||||
CryptoPP::Base32Encoder b32enc;
|
||||
b32enc.Detach(new CryptoPP::StringSink(ret));
|
||||
b32enc.Put(reinterpret_cast<CryptoPP::byte*>(&Source[0]), Source.size());
|
||||
if (ret == "")
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
else
|
||||
return HashResult::Success(RemoveWhiteChar(ret));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return HashResult::Faliure(HASH_LIBRARY_ERROR);
|
||||
}
|
||||
}
|
||||
case HashID::BASE32_HEX:
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string ret = "";
|
||||
CryptoPP::Base32HexEncoder b32enc_hex;
|
||||
b32enc_hex.Detach(new CryptoPP::StringSink(ret));
|
||||
b32enc_hex.Put(reinterpret_cast<CryptoPP::byte*>(&Source[0]), Source.size());
|
||||
if (ret == "")
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
else
|
||||
return HashResult::Success(RemoveWhiteChar(ret));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return HashResult::Faliure(HASH_LIBRARY_ERROR);
|
||||
}
|
||||
}
|
||||
case HashID::BASE36:
|
||||
{
|
||||
std::string out;
|
||||
if (basecodec::encodeBase36FromDecimalString(Source, out))
|
||||
return HashResult::Success(out);
|
||||
else
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
}
|
||||
case HashID::BASE58:
|
||||
return HashResult::Success(basecodec::encodeBase58(Source));
|
||||
case HashID::BASE62:
|
||||
return HashResult::Success(basecodec::encodeBase62(Source));
|
||||
case HashID::BASE64:
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string ret = "";
|
||||
CryptoPP::Base64Encoder b64enc;
|
||||
b64enc.Detach(new CryptoPP::StringSink(ret));
|
||||
b64enc.Put(reinterpret_cast<CryptoPP::byte*>(&Source[0]), Source.size());
|
||||
if (ret == "")
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
else
|
||||
return HashResult::Success(RemoveWhiteChar(ret));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return HashResult::Faliure(HASH_LIBRARY_ERROR);
|
||||
}
|
||||
}
|
||||
case HashID::BASE64_URL:
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string ret = "";
|
||||
CryptoPP::Base64URLEncoder b64enc_url;
|
||||
b64enc_url.Detach(new CryptoPP::StringSink(ret));
|
||||
b64enc_url.Put(reinterpret_cast<CryptoPP::byte*>(&Source[0]), Source.size());
|
||||
if (ret == "")
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
else
|
||||
return HashResult::Success(RemoveWhiteChar(ret));
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return HashResult::Faliure(HASH_LIBRARY_ERROR);
|
||||
}
|
||||
}
|
||||
case HashID::BASE85:
|
||||
return HashResult::Success(basecodec::encodeBase85(Source));
|
||||
case HashID::BASE91:
|
||||
{
|
||||
std::string out;
|
||||
if (basecodec::encodeBase91(Source, out))
|
||||
return HashResult::Success(out);
|
||||
else
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
}
|
||||
case HashID::URL:
|
||||
return HashResult::Success(urlcodec::url_encode(Source));
|
||||
default:
|
||||
return HashResult::Faliure(INVALID_HASH_FUNCTION);
|
||||
}
|
||||
return HashResult::Faliure(INVALID_HASH_FUNCTION);
|
||||
}
|
||||
else
|
||||
{
|
||||
int HashSize = CalculateHashSize(HashID);
|
||||
if (HashSize < 8)
|
||||
return HashResult::Faliure(INVALID_HASH_FUNCTION);
|
||||
char* src = new char[Source.length() + 1];
|
||||
unsigned char* dst = new unsigned char[(HashSize * 4) + 1];
|
||||
char* str = new char[HashSize + 1];
|
||||
strcpy(src, Source.c_str());
|
||||
memset(dst, 0, sizeof(dst));
|
||||
memset(str, 0, sizeof(str));
|
||||
rhash_library_init();
|
||||
int res = rhash_msg((int)HashID, src, strlen(src), dst);
|
||||
if (res < 0)
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
rhash_print_bytes(str, dst, rhash_get_digest_size((int)HashID), (PickOutputType(HashID) | RHPR_UPPERCASE));
|
||||
std::string ret = std::string(str);
|
||||
delete[] src;
|
||||
delete[] dst;
|
||||
delete[] str;
|
||||
return HashResult((ret.length() >= 8), RemoveWhiteChar(ret), HASH_LIBRARY_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
HashResult UOHash::HashFile(HashID HashID, std::string File, int ex_output_bits)
|
||||
{
|
||||
if (HashID >= HashID::__RHASH_MAX)
|
||||
return HashResult::Faliure(INVALID_HASH_FUNCTION);
|
||||
if (!FileExist(File))
|
||||
return HashResult::Faliure(FILE_DOES_NOT_EXIST);
|
||||
int HashSize = CalculateHashSize(HashID);
|
||||
if (HashSize < 8)
|
||||
return HashResult::Faliure(INVALID_HASH_FUNCTION);
|
||||
unsigned char* dst = new unsigned char[(HashSize * 4) + 1];
|
||||
char* str = new char[HashSize + 1];
|
||||
rhash_library_init();
|
||||
int res = rhash_file((int)HashID, File.c_str(), dst);
|
||||
if (res < 0)
|
||||
return HashResult::Faliure(HASH_CALCULATION_ERROR);
|
||||
rhash_print_bytes(str, dst, rhash_get_digest_size((int)HashID), (PickOutputType(HashID) | RHPR_UPPERCASE));
|
||||
std::string ret = std::string(str);
|
||||
delete[] dst;
|
||||
delete[] str;
|
||||
return HashResult((ret.length() >= 8), RemoveWhiteChar(ret), HASH_LIBRARY_ERROR);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include "Public.h"
|
||||
|
||||
namespace uns
|
||||
{
|
||||
class UOHASH_DLL_API UOHash
|
||||
{
|
||||
public:
|
||||
UOHash() = delete;
|
||||
UOHash(const UOHash& obj) = delete;
|
||||
private:
|
||||
static constexpr auto INVALID_HASHEX_ARGUMENT = "Invalid HashEx Argument";
|
||||
static constexpr auto HASH_CALCULATION_ERROR = "Hash Calculation Error";
|
||||
static constexpr auto INVALID_HASH_FUNCTION = "Invalid Hash Function";
|
||||
static constexpr auto FILE_DOES_NOT_EXIST = "File Doesn't Exist";
|
||||
static constexpr auto HASH_LIBRARY_ERROR = "Hash Library Error";
|
||||
static constexpr auto HASH_FUNCTION_CODING = "Hash Function Developing";
|
||||
private:
|
||||
static bool FileExist(std::string file);
|
||||
static int CalculateHashSize(HashID HashID);
|
||||
static std::string RemoveWhiteChar(std::string str);
|
||||
static int CalculateHashExSize(HashID HashID, int output_bits = 0);
|
||||
static rhash_print_sum_flags PickOutputType(HashID HashID);
|
||||
public:
|
||||
static HashResult DecodeString(HashID HashID, std::string Source);
|
||||
static HashResult HashString(HashID HashID, std::string Source, int ex_output_bits = 128);
|
||||
static HashResult HashFile(HashID HashID, std::string File, int ex_output_bits = 128);
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,182 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>18.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{696fff0a-4392-4ea6-8e41-1cb3867c4366}</ProjectGuid>
|
||||
<RootNamespace>UOHash</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetName>$(ProjectName)d</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;UOHASH_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableSegmentHeap>true</EnableSegmentHeap>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;UOHASH_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableSegmentHeap>true</EnableSegmentHeap>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;UOHASH_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableSegmentHeap>true</EnableSegmentHeap>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;UOHASH_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
<Manifest>
|
||||
<EnableSegmentHeap>true</EnableSegmentHeap>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="base36_codec.hpp" />
|
||||
<ClInclude Include="basecodec.hpp" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="JsonUnicodeWriter.h" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="Public.h" />
|
||||
<ClInclude Include="UOHash.h" />
|
||||
<ClInclude Include="URLCodec.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="JsonUnicodeWriter.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Public.cpp" />
|
||||
<ClCompile Include="UOHash.cpp" />
|
||||
<ClCompile Include="URLCodec.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="源文件">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="头文件">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="资源文件">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="framework.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="base36_codec.hpp">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="basecodec.hpp">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonUnicodeWriter.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Public.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="UOHash.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="URLCodec.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonUnicodeWriter.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Public.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="UOHash.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="URLCodec.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "URLCodec.h"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <cctype>
|
||||
|
||||
// 编码函数实现
|
||||
// 参考 Python 的 urllib.parse.quote 实现
|
||||
std::string urlcodec::url_encode(const std::string& input)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
for (const auto& ch : input)
|
||||
{
|
||||
// 保留字母、数字和部分符号
|
||||
if (std::isalnum(static_cast<unsigned char>(ch)) || ch == '-' || ch == '_' || ch == '.' || ch == '~')
|
||||
oss << ch;
|
||||
else // 其他字符进行百分号编码
|
||||
oss << '%' << std::uppercase << std::setw(2) << std::setfill('0') << std::hex << static_cast<int>(static_cast<unsigned char>(ch));
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
// 解码函数实现
|
||||
// 参考 Python 的 urllib.parse.unquote 实现
|
||||
bool urlcodec::url_decode(const std::string& input, std::string& output)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
size_t length = input.length();
|
||||
|
||||
for (size_t i = 0; i < length; ++i)
|
||||
{
|
||||
if (input[i] == '%')
|
||||
{
|
||||
if (i + 2 >= length)
|
||||
return false; // 错误:不完整的百分号编码
|
||||
std::string hex_str = input.substr(i + 1, 2);
|
||||
if (!std::isxdigit(hex_str[0]) || !std::isxdigit(hex_str[1]))
|
||||
return false; // 错误:无效的十六进制字符
|
||||
char decoded_char = static_cast<char>(std::stoi(hex_str, nullptr, 16));
|
||||
oss << decoded_char;
|
||||
i += 2; // 跳过已处理的两个字符
|
||||
}
|
||||
else
|
||||
oss << input[i];
|
||||
}
|
||||
output = oss.str();
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace urlcodec
|
||||
{
|
||||
// 编码函数:将输入字符串进行 URL 编码
|
||||
// 类似于 Python 的 urllib.parse.quote
|
||||
// 输入:原始字符串
|
||||
// 输出:编码后的字符串
|
||||
std::string url_encode(const std::string& input);
|
||||
|
||||
// 解码函数:将 URL 编码的字符串解码为原始字符串
|
||||
// 类似于 Python 的 urllib.parse.unquote
|
||||
// 输入:编码后的字符串
|
||||
// 输出:原始字符串
|
||||
// 返回值:true 表示解码成功,false 表示解码过程中出现错误
|
||||
bool url_decode(const std::string& input, std::string& output);
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
#pragma once
|
||||
// base36_codec.hpp
|
||||
#ifndef BASE36_CODEC_HPP
|
||||
#define BASE36_CODEC_HPP
|
||||
|
||||
#include <string>
|
||||
#include <cctype>
|
||||
#include <limits>
|
||||
#include <charconv>
|
||||
|
||||
//By ChatGPT: 1:1 converted from base36 library source code
|
||||
namespace basecodec
|
||||
{
|
||||
// Base36 alphabet
|
||||
inline constexpr const char* base36_alphabet = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
// Python: line 17
|
||||
// def dumps(number):
|
||||
inline bool encodeBase36(int64_t number, std::string& result) noexcept
|
||||
{
|
||||
result.clear();
|
||||
|
||||
// Python: line 23
|
||||
if (number < 0)
|
||||
{
|
||||
std::string positive;
|
||||
if (!encodeBase36(-number, positive))
|
||||
return false;
|
||||
result = '-' + positive;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Python: line 26
|
||||
if (number == 0)
|
||||
{
|
||||
result = "0";
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string value;
|
||||
while (number != 0)
|
||||
{
|
||||
int remainder = number % 36;
|
||||
number /= 36;
|
||||
value.insert(value.begin(), base36_alphabet[remainder]);
|
||||
}
|
||||
|
||||
result = std::move(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool encodeBase36FromDecimalString(const std::string& decimalStr, std::string& base36Out) noexcept
|
||||
{
|
||||
uint64_t number = 0;
|
||||
auto [ptr, ec] = std::from_chars(decimalStr.data(), decimalStr.data() + decimalStr.size(), number, 10);
|
||||
if (ec != std::errc())
|
||||
return false;
|
||||
|
||||
static const char alphabet[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
std::string result;
|
||||
do
|
||||
{
|
||||
result.insert(result.begin(), alphabet[number % 36]);
|
||||
number /= 36;
|
||||
}
|
||||
while (number != 0);
|
||||
|
||||
base36Out = result;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Python: line 35
|
||||
// def loads(value):
|
||||
inline bool decodeBase36(const std::string& input, int64_t& number) noexcept
|
||||
{
|
||||
// Validate input: allow optional leading '-', rest must be base36 chars
|
||||
size_t start = 0;
|
||||
bool negative = false;
|
||||
if (!input.empty() && input[0] == '-')
|
||||
{
|
||||
negative = true;
|
||||
start = 1;
|
||||
}
|
||||
|
||||
if (start == input.size())
|
||||
return false; // "-" alone is invalid
|
||||
|
||||
number = 0;
|
||||
for (size_t i = start; i < input.size(); ++i)
|
||||
{
|
||||
char c = std::tolower(input[i]);
|
||||
int digit;
|
||||
if (c >= '0' && c <= '9')
|
||||
digit = c - '0';
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
digit = c - 'a' + 10;
|
||||
else
|
||||
return false; // invalid character
|
||||
#pragma push_macro("max")
|
||||
#undef max
|
||||
if (number > (std::numeric_limits<int64_t>::max() - digit) / 36)
|
||||
return false; // overflow
|
||||
#pragma pop_macro("max")
|
||||
number = number * 36 + digit;
|
||||
}
|
||||
|
||||
if (negative)
|
||||
number = -number;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool decodeBase36ToDecimalString(const std::string& base36Str, std::string& decimalOut) noexcept
|
||||
{
|
||||
uint64_t number = 0;
|
||||
for (char c : base36Str)
|
||||
{
|
||||
int digit = 0;
|
||||
if (c >= '0' && c <= '9')
|
||||
digit = c - '0';
|
||||
else if (c >= 'a' && c <= 'z')
|
||||
digit = c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'Z')
|
||||
digit = c - 'A' + 10; // case-insensitive
|
||||
else
|
||||
return false; // invalid character
|
||||
if (digit >= 36)
|
||||
return false;
|
||||
number = number * 36 + digit;
|
||||
}
|
||||
|
||||
// Convert number to string using std::to_string
|
||||
decimalOut = std::to_string(number);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace basecodec
|
||||
|
||||
#endif // BASE36_CODEC_HPP
|
||||
@@ -0,0 +1,508 @@
|
||||
#pragma once
|
||||
#ifndef BASECODEC_HPP
|
||||
#define BASECODEC_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cctype>
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
|
||||
//By ChatGPT: 1:1 converted from cpython library source code
|
||||
//base58 from base58 library
|
||||
namespace basecodec
|
||||
{
|
||||
|
||||
// -------------------------
|
||||
// Base16 (hex) encoding/decoding
|
||||
// Converted from Python base16 implementation:
|
||||
// def b16encode(s): return binascii.hexlify(s).upper()
|
||||
// def b16decode(s, casefold=False): ... binascii.unhexlify(s)
|
||||
// Python source around lines 290-320 in base64.py
|
||||
// -------------------------
|
||||
|
||||
// Encode to hex, always succeeds
|
||||
inline std::string b16encode(const std::vector<uint8_t>& data)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << std::uppercase << std::hex;
|
||||
for (auto byte : data)
|
||||
oss << std::setw(2) << std::setfill('0') << static_cast<int>(byte);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
// Decode from hex, returns success status; outputs bytes in 'out'
|
||||
inline bool b16decode(const std::string& s, std::vector<uint8_t>& out, bool casefold = false)
|
||||
{
|
||||
std::string str = s;
|
||||
if (casefold)
|
||||
{
|
||||
for (auto& c : str)
|
||||
c = std::toupper(static_cast<unsigned char>(c));
|
||||
}
|
||||
if (str.size() % 2 != 0)
|
||||
return false; // invalid length
|
||||
out.clear();
|
||||
out.reserve(str.size() / 2);
|
||||
for (size_t i = 0; i < str.size(); i += 2)
|
||||
{
|
||||
auto val = [&] (char c) -> int
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
return -1;
|
||||
};
|
||||
int high = val(str[i]);
|
||||
int low = val(str[i + 1]);
|
||||
if (high < 0 || low < 0)
|
||||
{
|
||||
out.clear();
|
||||
return false; // non-hex digit
|
||||
}
|
||||
out.push_back(static_cast<uint8_t>((high << 4) | low));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// Base85 encoding/decoding (Z85-compatible)
|
||||
// Converted from Python base85 implementation:
|
||||
// def b85encode(b, pad=False): ... _85encode(...)
|
||||
// def b85decode(b): ...
|
||||
// Python source around lines 550-650 in base64.py
|
||||
// -------------------------
|
||||
|
||||
// Base85 alphabet as per Python _b85alphabet
|
||||
inline const std::string& _b85alphabet()
|
||||
{
|
||||
static const std::string alphabet =
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
|
||||
return alphabet;
|
||||
}
|
||||
|
||||
// Precomputed table of 85x85 two-character combos
|
||||
inline const std::vector<std::string>& _b85chars2()
|
||||
{
|
||||
static std::vector<std::string> table;
|
||||
if (table.empty())
|
||||
{
|
||||
const auto& alph = _b85alphabet();
|
||||
table.reserve(85 * 85);
|
||||
for (char a : alph)
|
||||
for (char b : alph)
|
||||
table.emplace_back(std::string{a, b});
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
// Encode bytes to Z85 string, always succeeds
|
||||
inline std::string b85encode(const std::vector<uint8_t>& data, bool pad = false)
|
||||
{
|
||||
const auto& alph = _b85alphabet();
|
||||
const auto& table2 = _b85chars2();
|
||||
size_t len = data.size();
|
||||
size_t padding = (4 - (len % 4)) % 4;
|
||||
std::vector<uint8_t> bytes = data;
|
||||
if (padding)
|
||||
bytes.insert(bytes.end(), padding, 0);
|
||||
|
||||
std::string result;
|
||||
result.reserve((bytes.size() / 4) * 5);
|
||||
for (size_t i = 0; i < bytes.size(); i += 4)
|
||||
{
|
||||
uint32_t acc =
|
||||
(uint32_t(bytes[i]) << 24) |
|
||||
(uint32_t(bytes[i + 1]) << 16) |
|
||||
(uint32_t(bytes[i + 2]) << 8) |
|
||||
uint32_t(bytes[i + 3]);
|
||||
uint32_t idx1 = acc / 614125; // 85^3
|
||||
uint32_t idx2 = (acc / 85) % 7225; // 85^2
|
||||
uint32_t idx3 = acc % 85;
|
||||
result += table2[idx1];
|
||||
result += table2[idx2];
|
||||
result.push_back(alph[idx3]);
|
||||
}
|
||||
if (padding && !pad)
|
||||
result.resize(result.size() - padding);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Decode Z85 string to bytes, returns success status; outputs bytes in 'out'
|
||||
inline bool b85decode(const std::string& s, std::vector<uint8_t>& out)
|
||||
{
|
||||
const auto& alph = _b85alphabet();
|
||||
static std::array<int, 256> dec;
|
||||
static bool init = false;
|
||||
if (!init)
|
||||
{
|
||||
dec.fill(-1);
|
||||
for (size_t i = 0; i < alph.size(); ++i)
|
||||
dec[static_cast<unsigned char>(alph[i])] = int(i);
|
||||
init = true;
|
||||
}
|
||||
size_t len = s.size();
|
||||
size_t padding = (5 - (len % 5)) % 5;
|
||||
std::string str = s;
|
||||
str.append(padding, alph[0]);
|
||||
|
||||
out.clear();
|
||||
out.reserve((str.size() / 5) * 4);
|
||||
for (size_t i = 0; i < str.size(); i += 5)
|
||||
{
|
||||
uint32_t acc = 0;
|
||||
for (size_t j = 0; j < 5; ++j)
|
||||
{
|
||||
int v = dec[static_cast<unsigned char>(str[i + j])];
|
||||
if (v < 0)
|
||||
{
|
||||
out.clear();
|
||||
return false; // bad base85 char
|
||||
}
|
||||
acc = acc * 85 + uint32_t(v);
|
||||
}
|
||||
out.push_back(uint8_t((acc >> 24) & 0xFF));
|
||||
out.push_back(uint8_t((acc >> 16) & 0xFF));
|
||||
out.push_back(uint8_t((acc >> 8) & 0xFF));
|
||||
out.push_back(uint8_t(acc & 0xFF));
|
||||
}
|
||||
if (padding)
|
||||
out.resize(out.size() - padding);
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// Base58 encoding/decoding (bitcoin-compatible)
|
||||
// Converted from Python base58 implementation (base58.py)
|
||||
// -------------------------
|
||||
|
||||
inline const std::string& b58_alphabet()
|
||||
{
|
||||
static const std::string alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
return alphabet;
|
||||
}
|
||||
|
||||
inline std::string b58encode(const std::vector<uint8_t>& data)
|
||||
{
|
||||
const auto& alph = b58_alphabet();
|
||||
std::string result;
|
||||
uint64_t num = 0;
|
||||
for (uint8_t b : data) num = (num << 8) | b;
|
||||
|
||||
while (num > 0)
|
||||
{
|
||||
result.insert(result.begin(), alph[num % 58]);
|
||||
num /= 58;
|
||||
}
|
||||
|
||||
for (uint8_t b : data)
|
||||
{
|
||||
if (b == 0x00)
|
||||
result.insert(result.begin(), alph[0]);
|
||||
else
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool b58decode(const std::string& s, std::vector<uint8_t>& out)
|
||||
{
|
||||
const auto& alph = b58_alphabet();
|
||||
std::unordered_map<char, int> index;
|
||||
for (size_t i = 0; i < alph.size(); ++i)
|
||||
index[alph[i]] = int(i);
|
||||
|
||||
uint64_t num = 0;
|
||||
for (char c : s)
|
||||
{
|
||||
if (index.find(c) == index.end())
|
||||
return false;
|
||||
num = num * 58 + index[c];
|
||||
}
|
||||
|
||||
std::vector<uint8_t> tmp;
|
||||
while (num > 0)
|
||||
{
|
||||
tmp.insert(tmp.begin(), static_cast<uint8_t>(num & 0xFF));
|
||||
num >>= 8;
|
||||
}
|
||||
|
||||
for (char c : s)
|
||||
{
|
||||
if (c == alph[0])
|
||||
tmp.insert(tmp.begin(), 0x00);
|
||||
else
|
||||
break;
|
||||
}
|
||||
out = tmp;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline std::string encodeBase58(const std::string& input) noexcept
|
||||
{
|
||||
return b58encode(std::vector<uint8_t>(input.begin(), input.end()));
|
||||
}
|
||||
|
||||
inline bool decodeBase58(const std::string& input, std::string& output)
|
||||
{
|
||||
std::vector<uint8_t> data;
|
||||
if (!b58decode(input, data)) return false;
|
||||
output.assign(data.begin(), data.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// Convenience string-based interface
|
||||
// -------------------------
|
||||
|
||||
// Encode std::string (raw bytes) to Base16 string
|
||||
// Returns encoded string
|
||||
inline std::string encodeBase16(const std::string& input) noexcept
|
||||
{
|
||||
std::vector<uint8_t> data(input.begin(), input.end());
|
||||
return b16encode(data);
|
||||
}
|
||||
|
||||
// Decode Base16 string to std::string (raw bytes)
|
||||
// Returns success flag, output in 'output'
|
||||
inline bool decodeBase16(const std::string& input, std::string& output, bool casefold = false)
|
||||
{
|
||||
std::vector<uint8_t> data;
|
||||
if (!b16decode(input, data, casefold))
|
||||
return false;
|
||||
output.assign(data.begin(), data.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Encode std::string (raw bytes) to Base85 string
|
||||
// Returns encoded string
|
||||
inline std::string encodeBase85(const std::string& input, bool pad = false) noexcept
|
||||
{
|
||||
std::vector<uint8_t> data(input.begin(), input.end());
|
||||
return b85encode(data, pad);
|
||||
}
|
||||
|
||||
// Decode Base85 string to std::string (raw bytes)
|
||||
// Returns success flag, output in 'output'
|
||||
inline bool decodeBase85(const std::string& input, std::string& output)
|
||||
{
|
||||
std::vector<uint8_t> data;
|
||||
if (!b85decode(input, data))
|
||||
return false;
|
||||
output.assign(data.begin(), data.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// Base62 encoding/decoding (Python source: base62.py)
|
||||
// -------------------------
|
||||
|
||||
inline const std::string& b62_charset_default()
|
||||
{
|
||||
static const std::string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
return charset;
|
||||
}
|
||||
|
||||
inline int b62_char_value(char ch, const std::string& charset)
|
||||
{
|
||||
auto pos = charset.find(ch);
|
||||
if (pos == std::string::npos)
|
||||
return -1;
|
||||
return static_cast<int>(pos);
|
||||
}
|
||||
|
||||
inline std::string b62encode(uint64_t num, const std::string& charset = b62_charset_default())
|
||||
{
|
||||
// From encode() function
|
||||
std::string result;
|
||||
if (num == 0)
|
||||
return "0";
|
||||
while (num > 0)
|
||||
{
|
||||
result.insert(result.begin(), charset[num % 62]);
|
||||
num /= 62;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline std::string encodeBase62(const std::string& input) noexcept
|
||||
{
|
||||
// From encodebytes() function
|
||||
const std::string& charset = b62_charset_default();
|
||||
std::vector<uint8_t> barray(input.begin(), input.end());
|
||||
|
||||
int leading_zeros = 0;
|
||||
for (auto b : barray)
|
||||
{
|
||||
if (b != 0)
|
||||
break;
|
||||
leading_zeros++;
|
||||
}
|
||||
|
||||
int n = static_cast<int>(leading_zeros / (charset.size() - 1));
|
||||
int r = static_cast<int>(leading_zeros % (charset.size() - 1));
|
||||
std::string zero_padding(n, '0');
|
||||
zero_padding += std::string(n, charset.back());
|
||||
if (r)
|
||||
zero_padding += "0" + std::string(1, charset[r]);
|
||||
|
||||
if (leading_zeros == static_cast<int>(barray.size()))
|
||||
return zero_padding;
|
||||
|
||||
uint64_t value = 0;
|
||||
for (uint8_t b : barray)
|
||||
value = (value << 8) | b;
|
||||
|
||||
return zero_padding + b62encode(value, charset);
|
||||
}
|
||||
|
||||
inline uint64_t b62decode(const std::string& s, const std::string& charset = b62_charset_default())
|
||||
{
|
||||
// From decode() function
|
||||
uint64_t value = 0;
|
||||
for (char ch : s)
|
||||
{
|
||||
int v = b62_char_value(ch, charset);
|
||||
if (v < 0)
|
||||
return 0; // indicates failure
|
||||
value = value * 62 + v;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
inline bool decodeBase62(const std::string& input, std::string& output)
|
||||
{
|
||||
// From decodebytes() function
|
||||
const std::string& charset = b62_charset_default();
|
||||
size_t i = 0;
|
||||
std::vector<uint8_t> result;
|
||||
|
||||
while (i + 1 < input.size() && input[i] == '0')
|
||||
{
|
||||
int count = b62_char_value(input[i + 1], charset);
|
||||
if (count < 0)
|
||||
return false;
|
||||
result.insert(result.end(), count, 0x00);
|
||||
i += 2;
|
||||
}
|
||||
|
||||
if (i >= input.size())
|
||||
{
|
||||
output.assign(result.begin(), result.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t decoded = b62decode(input.substr(i), charset);
|
||||
std::vector<uint8_t> temp;
|
||||
while (decoded > 0)
|
||||
{
|
||||
temp.push_back(decoded & 0xFF);
|
||||
decoded >>= 8;
|
||||
}
|
||||
std::reverse(temp.begin(), temp.end());
|
||||
result.insert(result.end(), temp.begin(), temp.end());
|
||||
|
||||
output.assign(result.begin(), result.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// Base91 encoding/decoding (Python source: encode/decode functions)
|
||||
// -------------------------
|
||||
|
||||
inline const std::string& b91_alphabet()
|
||||
{
|
||||
static const std::string alphabet =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[\\]^_`{|}~\"";
|
||||
return alphabet;
|
||||
}
|
||||
|
||||
inline bool encodeBase91(const std::string& input, std::string& output) noexcept
|
||||
{
|
||||
// From encode(bindata)
|
||||
const std::string& alphabet = b91_alphabet();
|
||||
uint32_t b = 0;
|
||||
int n = 0;
|
||||
output.clear();
|
||||
|
||||
for (uint8_t byte : input)
|
||||
{
|
||||
b |= static_cast<uint32_t>(byte) << n;
|
||||
n += 8;
|
||||
if (n > 13)
|
||||
{
|
||||
uint32_t v = b & 8191;
|
||||
if (v > 88)
|
||||
{
|
||||
b >>= 13;
|
||||
n -= 13;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = b & 16383;
|
||||
b >>= 14;
|
||||
n -= 14;
|
||||
}
|
||||
output += alphabet[v % 91];
|
||||
output += alphabet[v / 91];
|
||||
}
|
||||
}
|
||||
if (n)
|
||||
{
|
||||
output += alphabet[b % 91];
|
||||
if (n > 7 || b > 90)
|
||||
output += alphabet[b / 91];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool decodeBase91(const std::string& input, std::string& output) noexcept
|
||||
{
|
||||
// From decode(encoded_str)
|
||||
const std::string& alphabet = b91_alphabet();
|
||||
std::unordered_map<char, int> decode_table;
|
||||
for (size_t i = 0; i < alphabet.size(); ++i)
|
||||
decode_table[alphabet[i]] = static_cast<int>(i);
|
||||
|
||||
int v = -1;
|
||||
uint32_t b = 0;
|
||||
int n = 0;
|
||||
std::vector<uint8_t> result;
|
||||
|
||||
for (char c : input)
|
||||
{
|
||||
if (decode_table.find(c) == decode_table.end())
|
||||
continue;
|
||||
int val = decode_table[c];
|
||||
if (v < 0)
|
||||
v = val;
|
||||
else
|
||||
{
|
||||
v += val * 91;
|
||||
b |= v << n;
|
||||
n += (v & 8191) > 88 ? 13 : 14;
|
||||
while (n >= 8)
|
||||
{
|
||||
result.push_back(b & 255);
|
||||
b >>= 8;
|
||||
n -= 8;
|
||||
}
|
||||
v = -1;
|
||||
}
|
||||
}
|
||||
if (v != -1)
|
||||
result.push_back((b | (v << n)) & 255);
|
||||
|
||||
output.assign(result.begin(), result.end());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace basecodec
|
||||
|
||||
#endif // BASECODEC_HPP
|
||||
@@ -0,0 +1,16 @@
|
||||
// dllmain.cpp : 定义 DLL 应用程序的入口点。
|
||||
#include "pch.h"
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
|
||||
// Windows 头文件
|
||||
#include <windows.h>
|
||||
@@ -0,0 +1,5 @@
|
||||
// pch.cpp: 与预编译标头对应的源文件
|
||||
|
||||
#include "pch.h"
|
||||
|
||||
// 当使用预编译的头时,需要使用此源文件,编译才能成功。
|
||||
@@ -0,0 +1,13 @@
|
||||
// pch.h: 这是预编译标头文件。
|
||||
// 下方列出的文件仅编译一次,提高了将来生成的生成性能。
|
||||
// 这还将影响 IntelliSense 性能,包括代码完成和许多代码浏览功能。
|
||||
// 但是,如果此处列出的文件中的任何一个在生成之间有更新,它们全部都将被重新编译。
|
||||
// 请勿在此处添加要频繁更新的文件,这将使得性能优势无效。
|
||||
|
||||
#ifndef PCH_H
|
||||
#define PCH_H
|
||||
|
||||
// 添加要在此处预编译的标头
|
||||
#include "framework.h"
|
||||
|
||||
#endif //PCH_H
|
||||
Reference in New Issue
Block a user