PxCrypt v0.1
Encrypt data within an image
|
The Encoder class provides serialization of binary data to portions of an arbitrary image's color channels.
#include <>>
Public Types | |
enum | Encoding : quint8 { Relative , Absolute } |
Public Member Functions | |
Encoder () | |
quint8 | bpc () const |
QImage | encode (QByteArrayView payload, const QImage &medium) |
Encoding | encoding () const |
EncodeError | error () const |
bool | hasError () const |
QByteArray | presharedKey () const |
void | reset () |
void | setBpc (quint8 bpc) |
void | setEncoding (Encoding enc) |
void | setPresharedKey (const QByteArray &key) |
void | setTag (const QString tag) |
QString | tag () const |
Static Public Member Functions | |
static quint64 | calculateMaximumStorage (const QSize &dim, quint16 tagSize, quint8 bpc) |
static quint8 | calculateOptimalDensity (const QSize &dim, quint16 tagSize, quint32 payloadSize) |
enum PxCrypt::Encoder::Encoding : quint8 |
This enum specifies the encoding strategy utilized when encoding/decoding data, which affects several aspects of the resultant image.
This is the default encoding strategy.
The input data is broken up into 1-7 bit-wide frames in according to the value selected for bits per channel which are then woven into existing pixel data with each frame being mapped to one channel of a given pixel. This is accomplished by applying an offset to the original color channel value that matches the magnitude of the frame. The frame is subtracted from the original value if it is greater than 127
; otherwise, the frame is added to the original value.
Because the data is not stored directly in the image, but rather as the difference between the original image and the encrypted image, the is no way to know what the offset for each channel was without a point of reference, and thus the original medium image is required in order to decode the encoded data. Payloads are more securely protected using this method.
The effect each frame has on a given channel is directly proportional to its magnitude, with higher value frames causing greater distortion in the original image. The best case scenario occurs when the frame has a value of zero, while the worst is when the frame contains the maximum value allowed by the BPC setting. Overall this means that the choice of medium has no effect on the amount of distortion and that the degree of distortion at a given BPC is influenced entirely by the input payload when using this strategy, with ideal data consisting largely of low bits.
Best Case) 0
Worst Case) 2N - 1 (where N = bits per channel)
Input data is broken up into frames in the same manner as the Relative strategy, but are simply inserted directly into a pixel's channel data by replacing the lowest bits up to amount allowed by the BPC value. This allows the convenience of not requiring the original medium to decode the encrypted data, but at the cost of security since the output image relies entirely on the strength of the pre shared key for protection.
With this strategy the potential distortion caused by each frame depends on both the input data and the selected medium, as the degree of change is dictated by how different the frame is compared to the original bits that are being replaced. The best case scenario occurs when the frames data matches the original exactly, while the worst is when it is completely different. This leads to the same range of potential impact on the original image as with the Relative strategy, but in theory means that this method can out perform said strategy on average when the variance of the payload closes matches the variance of the image's color data
Best Case) 0
Worst Case) 2N - 1 (where N = bits per channel)
Enumerator | |
---|---|
Relative | Requires the original medium in order to decode the encrypted data. |
Absolute | Does not require the original medium in order to decode the encrypted data. |
PxCrypt::Encoder::Encoder | ( | ) |
Constructs an encoder with default settings:
quint8 PxCrypt::Encoder::bpc | ( | ) | const |
Returns the number of bits-per-channel the encoder is configured to use.
|
static |
Returns the maximum number of bytes that can be stored within an image of dimensions dim and tag of size tagSize when using bpc bits per channel.
|
static |
Returns the minimum number of bits per channel required to store a payload of payloadSize along with a tag of tagSize within a medium image of dim dimensions. 0
is returned if the payload/tag cannot fit within those dimensions.
Using the lowest BPC necessary is optimal as it will produce in the least distortion per pixel and the most even spread of the encoded data, overall resulting in the most minimal visual disturbance of the original image.
QImage PxCrypt::Encoder::encode | ( | QByteArrayView | payload, |
const QImage & | medium | ||
) |
Encodes payload within the medium image medium and returns it.
The encoding is carried out in accordance with the current configuration of the encoder.
If the current BPC of the encoder is 0
, the best BPC for the given medium and payload will be determined automatically. Then, the encoder's BPC is set to that ideal value.
If encoding fails, a null image will be returned. Use error() to determine the cause. Further attempts to use encode() will be ignored until the error state is cleared via reset().
The encoded image will always use the format QImage::Format_ARGB32
or QImage::Format_RGB32
(depending on if medium has an alpha channel) regardless of the format of medium.
The image produced by this function must never undergo a reduction in fidelity in order to remain decodable. In other words, it must be stored in a format that uses 8 bits per color channel and holds at least the RGB channels, else the encoded data be corrupted. No data is encoded within the alpha channel so that can safely be discarded.
Conversion to a format with a higher bit-depth can still result in data corruption due to aliasing sustained while resampling.
A 32-bit PNG is generally recommended as an ideal container.
Encoder::Encoding PxCrypt::Encoder::encoding | ( | ) | const |
Returns the encoding strategy the encoder is configured to use.
EncodeError PxCrypt::Encoder::error | ( | ) | const |
Returns the error encountered while encoding, if any; otherwise, returns an invalid error.
bool PxCrypt::Encoder::hasError | ( | ) | const |
QByteArray PxCrypt::Encoder::presharedKey | ( | ) | const |
Returns the key the encoder is configured to use for data scrambling.
void PxCrypt::Encoder::reset | ( | ) |
Resets the error status of the encoder.
void PxCrypt::Encoder::setBpc | ( | quint8 | bpc | ) |
Sets the number of bits-per-channel the encoder is configured to use to bpc.
This settings directly determines the number of bits woven into each color channel of a pixel and affects total encoding capacity. A BPC of 0 will instruct the encoder to determine the optimal BPC count automatically.
void PxCrypt::Encoder::setEncoding | ( | Encoding | enc | ) |
Sets the encoding strategy to use to enc.
void PxCrypt::Encoder::setPresharedKey | ( | const QByteArray & | key | ) |
Sets key used for scrambling the encoding sequence to key.
This key will be required in order to decode the resultant encoded data. An empty string results in the use of a known/default encoding sequence.
void PxCrypt::Encoder::setTag | ( | const QString | tag | ) |
Sets the encoding tag to tag.
Payloads are coupled with the tag during encoding in order to aid in payload identification or allow for the storage of any other string-based metadata. The tag is stored as part of the encrypted stream, not in plain text.
The tag is optional and can be left empty.