11#include <promeki/config.h>
12#if PROMEKI_ENABLE_CORE
19PROMEKI_NAMESPACE_BEGIN
63template <
size_t N, u
int64_t Seed>
class ObfuscatedString {
74 consteval ObfuscatedString(
const char (&str)[N]) : _data{} {
75 uint64_t state = initState();
76 for (
size_t i = 0; i < N - 1; ++i) {
77 uint64_t key = keyAt(i);
78 unsigned char k0 =
static_cast<unsigned char>(key);
79 unsigned char k1 =
static_cast<unsigned char>(key >> 8);
80 unsigned char c =
static_cast<unsigned char>(str[i]);
85 c =
static_cast<unsigned char>(c +
static_cast<unsigned char>(state));
87 unsigned shift = (k1 & 0x07) | 1;
88 c =
static_cast<unsigned char>((c << shift) | (c >> (8 - shift)));
92 _data[i] =
static_cast<char>(c);
93 state = advanceState(state, c, key);
101 String decode()
const {
102 String out(N - 1,
'\0');
103 uint64_t state = initState();
104 for (
size_t i = 0; i < N - 1; ++i) {
105 uint64_t key = keyAt(i);
106 unsigned char k0 =
static_cast<unsigned char>(key);
107 unsigned char k1 =
static_cast<unsigned char>(key >> 8);
108 unsigned char c =
static_cast<unsigned char>(_data[i]);
113 unsigned shift = (k1 & 0x07) | 1;
114 c =
static_cast<unsigned char>((c >> shift) | (c << (8 - shift)));
116 c =
static_cast<unsigned char>(c -
static_cast<unsigned char>(state));
120 out.setCharAt(i, Char(
static_cast<char>(c)));
121 state = advanceState(state,
static_cast<unsigned char>(_data[i]), key);
130 operator String()
const {
return decode(); }
134 static constexpr uint64_t initState() {
135 uint64_t h = Seed * 0xbf58476d1ce4e5b9ULL;
137 h *= 0x94d049bb133111ebULL;
143 static constexpr uint64_t keyAt(
size_t i) {
145 (Seed ^ (
static_cast<uint64_t
>(i) * 0x9e3779b97f4a7c15ULL)) * 0xbf58476d1ce4e5b9ULL;
147 h *= 0x94d049bb133111ebULL;
153 static constexpr uint64_t advanceState(uint64_t state,
unsigned char cipher, uint64_t key) {
154 state ^=
static_cast<uint64_t
>(cipher) | (key << 8);
155 state *= 0x517cc1b727220a95ULL;
156 state ^= state >> 29;
171#define PROMEKI_OBFUSCATE_SEED \
172 (::promeki::fnv1a(__FILE__) ^ (static_cast<uint64_t>(__LINE__) * 0x9e3779b97f4a7c15ULL) ^ \
173 ::promeki::fnv1a(__DATE__ __TIME__))
185#define PROMEKI_OBFUSCATE(str) \
187 static constexpr auto _obf = ::promeki::ObfuscatedString<sizeof(str), PROMEKI_OBFUSCATE_SEED>(str); \
188 return _obf.decode(); \