crego
Version, currently master branch1 version
- master branchlatestJul 14, 2019
github.com/watzon/crego
Steganography library for Crystal
Installation
# Add this to your shard.yml
dependencies:
crego:
github: watzon/crego
branch: mastermaster is a branch, not a release, so this tracks it rather than pinning a version.
Then run:
shards installshard.yml
- Crystal
0.29.0- License
- MIT
- Author
- Chris
Dependencies
Runtime Dependencies
- stumpy_png~> 4.4.1github: stumpycr/stumpy_png
- stumpy_jpeg*github: reiswindy/stumpy_jpeg
README
crego
Crego is a (wip) steganography library for Crystal. For those who don't know what steganography is:
Steganography (/ˌstɛɡəˈnɒɡrəfi/ STEG-ə-NOG-rə-fee) is the practice of concealing a file, message, image, or video within another file, message, image, or video. The word steganography combines the Greek words steganos (στεγανός), meaning "covered, concealed, or protected", and graphein (γράφειν) meaning "writing". - Wikipedia
Image formats currently supported by crego are JPEG and PNG, but support is planned for BMP and GIF images as well.
Note: Work in progress. Doesn't actually work yet.
Installation
-
Add the dependency to your
shard.yml:dependencies: crego: github: watzon/crego -
Run
shards install
Usage
require "crego"
# Open an image as a Crego object
image = Crego.open("/path/to/image.png")
# Write some data to it
image.encode("Hello world")
# Save the altered image
image.write("/path/to/image.png")
It's as simple as that. Of course there are other options.
# Open a file
file = File.open("/path/to/image.jpeg")
# Create a Crego instance from the file (any IO will work, including strings)
image = Crego.from_io(file)
# You can also create an instance from a slice
data = File.read("/path/to/image.jpeg")
image = Crego.from_slice(data.to_slice)
# Or from a base64 encoded string
data = "base64:image/png..."
image = Crego.from_b64(data)
# Continue as before
How it works
Every image is a collection of pixels. The amount of bits per pixel is determined by the image's bitdepth. When you encode a value using Crego#encode it takes the raw bits and modifies the least significant bit of each pixel to match. This means that every byte takes 8 pixels and you can encode a maximum of (image total pixels / 8) bytes. In truth we probably could work with the two least significant bits and get away with it, but the more bits you change the more it affects the image.
With a Crencode encoded image the first 32 pixels (modified bits) tell Crencode the bitlength of the encoded data (which gives us a maximum of 4294967295 bits or roughly 536870911 bytes) which should be sufficient for most images. The rest of the pixels up to the length specified contain the encoded information.
Since this format is easily decoded you could also choose to encrypt the data beforehand using the cryptographic cypher of your choosing. You could also store anything in the image, not just text. Theoretically with a large enough image you could store a program, other images, or even a video.
Development
File an issue, open a PR, you know the deal :wink:
Contributing
- Fork it (https://github.com/watzon/crego/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Contributors
- Chris - creator and maintainer
Documentation
Built from the current release. The first visit to a release nobody has asked for starts its build.
Links
This branch
- Branch
master- Seen
- Jul 14, 2019
- Crystal
0.29.0- Indexed
- yes
Dependents
No indexed shard depends on this one yet.
Repository
github.com/watzon/crego
Metadata
- Created
- Aug 13, 2026
- Updated
- Aug 15, 2026
- Synced
- Aug 15, 2026
- Versions
- 1