The Fossil IO Cipher module provides a unified, string-identified interface for encoding and decoding text using a curated set of classical and utility ciphers such as Caesar, Vigenère, Base64, ROT13, and Morse. The C API exposes simple, stateless functions that perform cipher lookup via a static registry and return newly allocated results, making the module easy to embed and thread-safe by design. On top of this, the C++ wrapper offers a thin, header-only façade that integrates cleanly with std::string, enabling safer and more idiomatic use in modern C++ while preserving the ABI and behavior of the underlying C implementation.
Code reference for C and C++ APIs for the respective Fossil Logic library.
HEADER REFERENCE #
#ifndef FOSSIL_IO_CIPHER_H
#define FOSSIL_IO_CIPHER_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* Cipher Registry and Internal Logic
*
* This module provides unified encode/decode APIs for a set of supported text ciphers.
* Each cipher is identified by a string ID and registered in a static lookup table.
*
* Available cipher string IDs:
* - "caesar"
* - "vigenere"
* - "base64"
* - "base32"
* - "binary"
* - "morse"
* - "baconian"
* - "railfence"
* - "haxor"
* - "leet"
* - "rot13"
* - "atbash"
*
* Internal logic:
* - Ciphers are registered in a static table: static const cipher_entry cipher_table[].
* - Lookup is performed by string ID (case-insensitive) using a linear search (O(n) time).
* - Each cipher_entry contains the cipher's string ID and a function pointer.
* - The encode/decode API calls the cipher function with the input text and mode.
* - Cipher functions return a newly allocated string (caller must free).
* - If an unknown cipher ID is provided, the API returns NULL.
*
* Example usage:
* char *encoded = fossil_io_cipher_encode("Hello", "caesar");
* char *decoded = fossil_io_cipher_decode(encoded, "caesar");
* free(encoded);
* free(decoded);
*
* Notes:
* - All cipher functions are stateless and thread-safe.
* - The registry is static and not extensible at runtime.
* - The lookup is O(n) (linear in number of ciphers).
* - Input validation is performed; NULL is returned for invalid arguments.
* - The encode/decode APIs are symmetric for reversible ciphers.
* - Some ciphers (e.g., vigenere, railfence) use fixed parameters in this implementation.
* - The caller is responsible for freeing returned buffers.
*/
/**
* Encode text using a named cipher.
*
* Internal logic:
* - Ciphers are registered in cipher_table[].
* - Lookup is performed by string ID (case-insensitive).
* - Encode API selects the cipher and calls its function.
* - Returns a newly allocated string (caller must free).
* - If an unknown cipher ID is provided, returns NULL.
*
* Available cipher string IDs:
* - "caesar"
* - "vigenere"
* - "base64"
* - "base32"
* - "binary"
* - "morse"
* - "baconian"
* - "railfence"
* - "haxor"
* - "leet"
* - "rot13"
* - "atbash"
*/
char *fossil_io_cipher_encode(const char *text, const char *cipher_id);
/**
* Decode text using a named cipher.
*
* Internal logic:
* - Ciphers are registered in cipher_table[].
* - Lookup is performed by string ID (case-insensitive).
* - Decode API selects the cipher and calls its function.
* - Returns a newly allocated string (caller must free).
* - If an unknown cipher ID is provided, returns NULL.
*
* Available cipher string IDs:
* - "caesar"
* - "vigenere"
* - "base64"
* - "base32"
* - "binary"
* - "morse"
* - "baconian"
* - "railfence"
* - "haxor"
* - "leet"
* - "rot13"
* - "atbash"
*/
char *fossil_io_cipher_decode(const char *text, const char *cipher_id);
#ifdef __cplusplus
}
#include <string>
namespace fossil {
namespace io {
/**
* Cipher
*
* Thin C++ wrapper around Fossil IO cipher encode/decode API.
*
* This class:
* - Owns returned buffers safely
* - Does not throw
* - Does not allocate unless the C layer does
* - Is header-only and ABI-neutral
*/
class Cipher {
public:
/**
* Encode text using a named cipher.
*
* Internal logic:
* - Ciphers are registered in cipher_table[].
* - Lookup is performed by string ID (case-insensitive).
* - The encode API selects the cipher and calls its function.
* - Returns a newly allocated string (caller must free).
* - If an unknown cipher ID is provided, returns an empty string.
*
* Available cipher string IDs:
* - "caesar"
* - "vigenere"
* - "base64"
* - "base32"
* - "binary"
* - "morse"
* - "baconian"
* - "railfence"
* - "haxor"
* - "leet"
* - "rot13"
* - "atbash"
*/
static std::string encode(const std::string &text,
const std::string &cipher_id) {
return fossil_io_cipher_encode(text.c_str(), cipher_id.c_str());
}
/**
* Decode text using a named cipher.
*
* Internal logic:
* - Ciphers are registered in cipher_table[].
* - Lookup is performed by string ID (case-insensitive).
* - The decode API selects the cipher and calls its function.
* - Returns a newly allocated string (caller must free).
* - If an unknown cipher ID is provided, returns an empty string.
*
* Available cipher string IDs:
* - "caesar"
* - "vigenere"
* - "base64"
* - "base32"
* - "binary"
* - "morse"
* - "baconian"
* - "railfence"
* - "haxor"
* - "leet"
* - "rot13"
* - "atbash"
*/
static std::string decode(const std::string &text,
const std::string &cipher_id) {
return fossil_io_cipher_decode(text.c_str(), cipher_id.c_str());
}
};
} // namespace io
} // namespace fossil
#endif
#endif /* FOSSIL_IO_FRAMEWORK_H */SAMPLE CODE C #
#include "fossil/io/cipher.h"
#include <stdio.h>
#include <stdlib.h>
int main(void) {
const char *text = "Hello, World!";
/* Encode using a Caesar cipher */
char *encoded = fossil_io_cipher_encode(text, "caesar");
if (!encoded) {
fprintf(stderr, "Encoding failed\n");
return 1;
}
printf("Encoded: %s\n", encoded);
/* Decode back to original */
char *decoded = fossil_io_cipher_decode(encoded, "caesar");
if (!decoded) {
fprintf(stderr, "Decoding failed\n");
free(encoded);
return 1;
}
printf("Decoded: %s\n", decoded);
/* Caller owns the returned buffers */
free(encoded);
free(decoded);
return 0;
}
SAMPLE CODE C++ #
#include "fossil/io/cipher.h"
#include <iostream>
using fossil::io::Cipher;
int main() {
std::string text = "Attack at dawn";
/* Encode using ROT13 */
std::string encoded = Cipher::encode(text, "rot13");
if (encoded.empty()) {
std::cerr << "Encoding failed\n";
return 1;
}
std::cout << "Encoded: " << encoded << '\n';
/* Decode back */
std::string decoded = Cipher::decode(encoded, "rot13");
if (decoded.empty()) {
std::cerr << "Decoding failed\n";
return 1;
}
std::cout << "Decoded: " << decoded << '\n';
return 0;
}