| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- /**
- ******************************************************************************
- * @file : obfuscate.hpp
- * @author : Dream
- * @brief : None
- * @attention : None
- * @date : 2024/12/4
- ******************************************************************************
- */
- /*
- 原文作者:Adam Yaxley
- */
- #pragma once
- #if __cplusplus >= 202002L
- #define AY_CONSTEVAL consteval
- #else
- #define AY_CONSTEVAL constexpr
- #endif
- #ifdef _MSC_VER
- #define AY_CAT(X,Y) AY_CAT2(X,Y)
- #define AY_CAT2(X,Y) X##Y
- #define AY_LINE int(AY_CAT(__LINE__,U))
- #else
- #define AY_LINE __LINE__
- #endif
- #ifndef AY_OBFUSCATE_DEFAULT_KEY
- //用于混淆字符串的默认 64 位密钥
- //这可以通过在之前定义 AY_OBFUSCATE_DEFAULT_KEY 来由用户指定
- //包括 obfuscate.h
- #define AY_OBFUSCATE_DEFAULT_KEY ay::generate_key(AY_LINE)
- #endif
- namespace ay
- {
- using size_type = unsigned long long;
- using key_type = unsigned long long;
- template <typename T>
- struct remove_const_ref {
- using type = T;
- };
- template <typename T>
- struct remove_const_ref<T&> {
- using type = T;
- };
- template <typename T>
- struct remove_const_ref<const T> {
- using type = T;
- };
- template <typename T>
- struct remove_const_ref<const T&> {
- using type = T;
- };
- template <typename T>
- using char_type = typename remove_const_ref<T>::type;
- //生成一个跨越所有 8 个字节的伪随机键
- AY_CONSTEVAL key_type generate_key(key_type seed)
- {
- // 使用 MurmurHash3 64 位终结器对种子进行哈希处理
- key_type key = seed;
- key ^= (key >> 33);
- key *= 0xff51afd7ed558ccd;
- key ^= (key >> 33);
- key *= 0xc4ceb9fe1a85ec53;
- key ^= (key >> 33);
- // 确保设置每个字节中的位
- key |= 0x0101010101010101ull;
- return key;
- }
- // 使用 key 对数据进行混淆或反混淆
- template <typename CHAR_TYPE>
- constexpr void cipher(CHAR_TYPE* data, size_type size, key_type key)
- {
- // 使用基于密钥的简单 XOR 密码进行混淆
- for (size_type i = 0; i < size; i++)
- {
- data[i] ^= CHAR_TYPE((key >> ((i % 8) * 8)) & 0xFF);
- }
- }
- // 在编译时对字符串进行模糊处理
- template <size_type N, key_type KEY, typename CHAR_TYPE = char>
- class obfuscator
- {
- public:
- // 在构造时混淆字符串 'data'
- AY_CONSTEVAL obfuscator(const CHAR_TYPE* data)
- {
- // Copy data
- for (size_type i = 0; i < N; i++)
- {
- m_data[i] = data[i];
- }
- // On construction each of the characters in the string is
- // obfuscated with an XOR cipher based on key
- cipher(m_data, N, KEY);
- }
- constexpr const CHAR_TYPE* data() const
- {
- return &m_data[0];
- }
- AY_CONSTEVAL size_type size() const
- {
- return N;
- }
- AY_CONSTEVAL key_type key() const
- {
- return KEY;
- }
- private:
- CHAR_TYPE m_data[N]{};
- };
- // Handles decryption and re-encryption of an encrypted string at runtime
- template <size_type N, key_type KEY, typename CHAR_TYPE = char>
- class obfuscated_data
- {
- public:
- obfuscated_data(const obfuscator<N, KEY, CHAR_TYPE>& obfuscator)
- {
- // Copy obfuscated data
- for (size_type i = 0; i < N; i++)
- {
- m_data[i] = obfuscator.data()[i];
- }
- }
- ~obfuscated_data()
- {
- // Zero m_data to remove it from memory
- for (size_type i = 0; i < N; i++)
- {
- m_data[i] = 0;
- }
- }
- // Returns a pointer to the plain text string, decrypting it if
- // necessary
- operator CHAR_TYPE* ()
- {
- decrypt();
- return m_data;
- }
- // Manually decrypt the string
- void decrypt()
- {
- if (m_encrypted)
- {
- cipher(m_data, N, KEY);
- m_encrypted = false;
- }
- }
- // Manually re-encrypt the string
- void encrypt()
- {
- if (!m_encrypted)
- {
- cipher(m_data, N, KEY);
- m_encrypted = true;
- }
- }
- // Returns true if this string is currently encrypted, false otherwise.
- bool is_encrypted() const
- {
- return m_encrypted;
- }
- private:
- // Local storage for the string. Call is_encrypted() to check whether or
- // not the string is currently obfuscated.
- CHAR_TYPE m_data[N];
- // Whether data is currently encrypted
- bool m_encrypted{ true };
- };
- // This function exists purely to extract the number of elements 'N' in the
- // array 'data'
- template <size_type N, key_type KEY = AY_OBFUSCATE_DEFAULT_KEY, typename CHAR_TYPE = char>
- AY_CONSTEVAL auto make_obfuscator(const CHAR_TYPE(&data)[N])
- {
- return obfuscator<N, KEY, CHAR_TYPE>(data);
- }
- }
- #define AY_OBFUSCATE(data) AY_OBFUSCATE_KEY(data, AY_OBFUSCATE_DEFAULT_KEY)
- #define AY_OBFUSCATE_KEY(data, key) \
- []() -> ay::obfuscated_data<sizeof(data)/sizeof(data[0]), key, ay::char_type<decltype(*data)>>& { \
- static_assert(sizeof(decltype(key)) == sizeof(ay::key_type), "key must be a 64 bit unsigned integer"); \
- static_assert((key) >= (1ull << 56), "key must span all 8 bytes"); \
- using char_type = ay::char_type<decltype(*data)>; \
- constexpr auto n = sizeof(data)/sizeof(data[0]); \
- constexpr auto obfuscator = ay::make_obfuscator<n, key, char_type>(data); \
- thread_local auto obfuscated_data = ay::obfuscated_data<n, key, char_type>(obfuscator); \
- return obfuscated_data; \
- }()
|