-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
48 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,55 @@ | ||
# xorlit | ||
Compile time string literal encryptor | ||
# Example Usage | ||
Compile time string literal encryptor for C++. | ||
* [Usage](#usage) | ||
* [Example](#example) | ||
|
||
# Usage | ||
## XORLIT | ||
The `XORLIT` macro can be used to create an encrypted string which evaluates to its original contents (e.g. `XORLIT("foo")` would evalute as the string "foo", but be stored as some other encrypted value). As it wraps `xorlit::make_str`, one can pass either one argument, a string literal, or two arguments, a string literal and a key. In the case that one argument is passed, the key used will default to `xorlit::seed`. | ||
> [!WARNING] | ||
> Exercise caution when using `XORLIT`, `xorlit::make_str(__VA_ARGS__).rexor()`, or `xorlit::string`s in any context where they are not explicitly stored, as some compilers, such as MSVC, may sporadically encrypt strings non-constexpr-ly depending on the string literal's content or the context of its usage. It may be advisable to search binary contents for any unencrypted string literals in this case. | ||
## xorlit::seed | ||
`xorlit::seed` is a `constexpr std::uint_least32_t` which is based on the predefined `__TIME__` macro to generate values. It is the default value used by `xorlit::make_str` and by extension `XORLIT` for the key. Since `xorlit::seed` or `static_cast<char>(xorlit::seed)` may evaluate to 0, which, in such a case, would lead to an unencrypted string, by defining `XORLIT_SEED_STATIC_ASSERT` before including the `xorlit.hpp` header, a static assertion by the compiler will be enabled to check if `xorlit::seed` is equal to 0. | ||
|
||
## xorlit::string | ||
`xorlit::string` is the provided type for storing encrypted strings. A `xorlit::string` should always be decorated with the `constexpr` specifier to ensure it is stored in its encrypted form. | ||
`xorlit::string` defines the following member functions: | ||
* `xorlit::string::rexor()`: xors the data of the string and returns it. | ||
* `xorlit::string::xor_data()`: returns a new `const char*` with a copy of the string's data xored. | ||
* `xorlit::string::data`: returns the data stored in the string. `const` and non-`const` variants are provided. | ||
* `xorlit::string::key`: returns the key stored in the string. | ||
> [!IMPORTANT] | ||
> Results of `xorlit::string::xor_data()` must be managed manually, whether that be via `delete`, smart pointers, etc. | ||
# Example | ||
```c++ | ||
#include <string> | ||
#include <iostream> | ||
#include "xorlit.hpp" | ||
#include <format> | ||
#define XORLIT_SEED_STATIC_ASSERT // enable compiler check if xorlit::seed is 0 | ||
#include <xorlit.hpp> | ||
|
||
int main() | ||
{ | ||
std::cout << XORLITSTR("Hello world!"); | ||
return 0; | ||
std::cout | ||
<< XORLIT("Default, xorlit::seed is passed as the key\n") | ||
<< XORLIT("Or you can use xorlit::seed yourself\n", xorlit::seed + __LINE__) // when passing your own seeds, you should check that they aren't 0 | ||
<< XORLIT("Or you can choose your own key\n", 12) << std::endl; | ||
|
||
constexpr auto s = xorlit::make_str("You can manually store a xorlit::string"); // always declare the results of xorlit::make_str constexpr | ||
const std::string raw(s.data(), decltype(s)::size); | ||
const char* original_data = s.xor_data(); // results of xorlit::string::xor_data must be manually managed, smart pointers are recommended | ||
const std::string original(original_data, decltype(s)::size); | ||
delete[] original_data; | ||
std::cout << std::format("Raw: {}\nOriginal: {}", raw, original) << std::endl; | ||
} | ||
``` | ||
|
||
////////////////// Possible output: ////////////////// | ||
// Default, xorlit::seed is passed as the key | ||
// Or you can use xorlit::seed yourself | ||
// Or you can choose your own seed | ||
// | ||
// Raw: ?%p31>p=1>%1<<)p#$?"5p1p(?"<9$jj#$"9>7P | ||
// Original: You can manually store a xorlit::string | ||
``` |