Encrypted Images is distributed under the MIT License. [](https://opensource.org/licenses/MIT)
`encrypted_images` is a Rust crate for encrypting plaintext into ciphertext, encoding that ciphertext into PNG images, decoding the image back into ciphertext, and then decrypting it again. It supports optional watermarking, multiple output orientations, and a fixed-size image format designed to keep larger payloads practical.
For image encoding, the ciphertext should come from this crate's encryption flow, or otherwise be limited to characters supported by the internal color mapping used by the image encoder and decoder.
- Maximum plaintext length: implementation-dependent and far larger than the image layer
- Image encoding/decoding:
- The current image format uses a fixed `350x350` canvas
- Ciphertext is stored across 11 anchor rows
- The first 4 stored characters are reserved for payload length
- Maximum ciphertext payload per image: 3846 characters
If your ciphertext exceeds the image payload limit, image creation will fail and the data should be split across multiple images or handled outside the image layer.
+ `input`&str: The plaintext you want to encrypt. The default mode is primarily intended for novelty or deterministic use cases where identical input returning identical output is acceptable. For stronger security properties, use the optional settings.
+ `key` Option<&str>: The optional encryption key. The built-in default key is intended only for novelty usage. For real encrypted image usage, provide your own 16-character key.
+ `strength` Option<&str>: Controls whether encryption is deterministic or randomized.
-`default`: Deterministic novelty mode. The same input returns the same ciphertext every time.
-`advanced`: Randomized mode. The same input returns different ciphertext values over repeated runs, helping protect against comparison attacks.
## Decrypting Text
Decrypting text is the reverse of the encryption flow.
+ `encrypted_text`&str: The ciphertext previously produced by `encrypts`.
+ `key` Option<&str>: Use the same key that was used during encryption. If a custom key was used to encrypt the text, the same custom key must be provided for decryption.
Image encoding has 9 parameters, 6 of which are optional. The recommended input is ciphertext produced by this crate's encryption functions.
The current encoder uses a fixed `350x350` PNG canvas. Ciphertext is stored across evenly spaced anchor rows, and the rows between them are interpolated to preserve the striped visual style while keeping the overall image size practical.
-`v2`: Rotated and vertically flipped orientation.
Internally, the encoded data is stored on multiple anchor rows. These style options rotate or flip the final image representation, and the decoder tests the supported styles when extracting the ciphertext again.
When using a custom base64 watermark, the following optional settings must be present. They have no effect on the built-in default watermarks and should be set to `None` for those.
+ `a` Option<u8> (Range `0..=255`): Adjusts watermark alpha. If the image contains a transparent background, alpha is applied to the transparent region. If it does not, alpha is applied to the whole watermark.
In the current image format, watermark pixels are prevented from overwriting the protected data anchor rows. This keeps the stored ciphertext intact while still allowing an overlaid watermark between those rows.
Gradient settings are still part of the public function signature for compatibility, but the current fixed-grid renderer does not use `r`, `g`, or `b` to generate the image palette. If you do not need them for compatibility with older calling code, set them to `None`.
Decoding is straightforward. It accepts a single parameter: the encoded image as base64 PNG text.
The decoder understands the current fixed-grid format and tests the supported output orientations (`h`, `h2`, `v`, `v2`) while attempting to recover the ciphertext.
use encrypted_images::encryption::images::create_img;
fn main() {
let ciphertext = "VkdocGN5QkpjeUJRYkE9PZNY2MOW01NWpSxCtFG6acHuAWun+CElPQ/IIwd0gy+D+IiBqB/5+qo8Jr9bMBOwoih3amCtjXlkAlRKHX5fhqI=";
let style = "h";
let watermark = "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
let r = Some(100);
let g = Some(134);
let b = Some(137);
let a = Some(0);
let w = Some(32);
let h = Some(32);
if let Some(encoded_image) = create_img(ciphertext, style, watermark, r, g, b, a, w, h) {
let encoded_image = "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
let encoded_image = "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