<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Anjasfedo</title>
    <description>The latest articles on DEV Community by Anjasfedo (@anjasfedo).</description>
    <link>https://dev.to/anjasfedo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3931754%2Fcb0b9d4b-4191-4faf-a5ac-e859cc228640.jpeg</url>
      <title>DEV Community: Anjasfedo</title>
      <link>https://dev.to/anjasfedo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/anjasfedo"/>
    <language>en</language>
    <item>
      <title>Perfect Pixel Recovery: Implementing Bayesian Neural Networks for Reversible Steganography 🕵️‍♂️</title>
      <dc:creator>Anjasfedo</dc:creator>
      <pubDate>Tue, 19 May 2026 18:23:55 +0000</pubDate>
      <link>https://dev.to/anjasfedo/perfect-pixel-recovery-implementing-bayesian-neural-networks-for-reversible-steganography-55bl</link>
      <guid>https://dev.to/anjasfedo/perfect-pixel-recovery-implementing-bayesian-neural-networks-for-reversible-steganography-55bl</guid>
      <description>&lt;p&gt;Imagine hiding a secret message inside an image, transmitting it, and then extracting that exact message without losing a single bit. Now, imagine being able to restore the original cover image to its exact mathematical state, pixel for pixel. 🧩&lt;/p&gt;

&lt;p&gt;In this article, I will walk through my implementation of a research-backed architecture that uses Bayesian Neural Networks and Modulo-256 arithmetic to achieve 100% reversible steganography.&lt;/p&gt;




&lt;h2&gt;
  
  
  📜 Academic Attribution
&lt;/h2&gt;

&lt;p&gt;First and foremost, this work is an implementation and exploration of the research paper:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Bayesian Neural Networks for Reversible Steganography"&lt;br&gt;
Author: Ching-Chun Chang&lt;br&gt;
Journal: IEEE Access, 2022&lt;br&gt;
DOI: &lt;a href="https://doi.org/10.1109/ACCESS.2022.3159911" rel="noopener noreferrer"&gt;10.1109/ACCESS.2022.3159911&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All architectural foundations for the uncertainty-driven embedding, including the Bayesian Neural Network predictor and the variance-sorted difference expansion, are attributed to the original author.&lt;/p&gt;




&lt;h2&gt;
  
  
  📌 The Challenge: The Reversibility Problem
&lt;/h2&gt;

&lt;p&gt;Most traditional steganography permanently alters the cover image. Reversible steganography aims to fix this, but it faces a massive enemy: pixel overflow and underflow (clipping).&lt;/p&gt;

&lt;p&gt;If a pixel is purely white (255) and you add 1 to hide a secret bit, the image format clips it back to 255. When the receiver tries to read it, the math is broken, the secret bit is corrupted, and the image cannot be restored. 💥&lt;/p&gt;




&lt;h2&gt;
  
  
  🧬 Why Bayesian Neural Networks?
&lt;/h2&gt;

&lt;p&gt;The core innovation here is uncertainty estimation. Instead of just guessing pixel values, the network outputs two things: the predicted pixel intensity and its own uncertainty (variance).&lt;/p&gt;

&lt;p&gt;By predicting which pixels it is highly confident about, the network creates a variance map. We can then hide our secret message exclusively in the areas where the network is most certain. This ensures the visual distortion is kept to an absolute minimum. 🧠&lt;/p&gt;




&lt;h2&gt;
  
  
  🔄 The Modulo-256 Magic
&lt;/h2&gt;

&lt;p&gt;To completely defeat the clipping problem, this implementation uses Modulo-256 arithmetic. If a pixel at 255 gets a +1 modification, it rolls over to 0 instead of clipping.&lt;/p&gt;

&lt;p&gt;Because the receiver uses a checkerboard pattern to share the exact same neural network context, they can calculate the modulo difference and perfectly restore both the secret bit and the original pixel.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧮 The Mathematical Framework
&lt;/h2&gt;

&lt;p&gt;The system optimizes a custom uncertainty-weighted loss function. Instead of standard mean squared error, the loss penalizes errors based on the model's confidence:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;Loss=1N∑((y−y^)2σ2+λlog⁡(σ2))
Loss = \frac{1}{N} \sum \left( \frac{(y - \hat{y})^2}{\sigma^2} + \lambda \log(\sigma^2) \right)
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;L&lt;/span&gt;&lt;span class="mord mathnormal"&gt;oss&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;N&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mop op-symbol large-op"&gt;∑&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="minner"&gt;&lt;span class="mopen delimcenter"&gt;&lt;span class="delimsizing size3"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen nulldelimiter"&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;σ&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="frac-line"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord accent"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;y&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="accent-body"&gt;&lt;span class="mord"&gt;^&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose nulldelimiter"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;λ&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mop"&gt;lo&lt;span&gt;g&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;σ&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mclose delimcenter"&gt;&lt;span class="delimsizing size3"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;For the embedding process, the residual \epsilon (the difference between the true pixel and the prediction) is modulated with the secret bit m:&lt;/p&gt;


&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;ϵ′=(2×ϵ)+m(mod256)
\epsilon^{\prime} = (2 \times \epsilon) + m \pmod{256}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;ϵ&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mtight"&gt;′&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;2&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;×&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ϵ&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;m&lt;/span&gt;&lt;span class="mspace allowbreak"&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord"&gt;&lt;span class="mord mathrm"&gt;mod&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;256&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  📊 Experimental Results (The Trial Run)
&lt;/h2&gt;

&lt;p&gt;I trained the Bayesian predictor for 200 epochs on a dataset of standard test images. The payload size was set to approximately 0.3 bits per pixel (bpp).&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Visual Performance &amp;amp; Reversibility
&lt;/h3&gt;

&lt;p&gt;The system achieved 100% extraction success. Every single bit was recovered, and the images were restored flawlessly. For smooth images like Lena and Sailboat, the PSNR reached above 50 dB, meaning the stego image is visually indistinguishable from the original.&lt;/p&gt;

&lt;p&gt;Below are the visual results across different textures, demonstrating the system's ability to maintain imperceptibility (ranked from highest to lowest PSNR):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Sailboat&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MSE:&lt;/strong&gt; 0.5237&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PSNR:&lt;/strong&gt; 50.94 dB&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7we0xgxjugs9edlfez1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7we0xgxjugs9edlfez1.png" alt="Sailboat" width="799" height="276"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;2. Lena&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MSE:&lt;/strong&gt; 0.6204&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PSNR:&lt;/strong&gt; 50.20 dB&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gdd3l1m4u3p9b95u9y2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gdd3l1m4u3p9b95u9y2.png" alt="Lena" width="799" height="276"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;3. Airplane&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MSE:&lt;/strong&gt; 0.7910&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PSNR:&lt;/strong&gt; 49.15 dB&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcey196tpn8u4bh84wccw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcey196tpn8u4bh84wccw.png" alt="Airplane" width="799" height="276"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;4. Baboon&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MSE:&lt;/strong&gt; 1.7721&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PSNR:&lt;/strong&gt; 45.65 dB&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1u7cpooi991zagxwgm99.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1u7cpooi991zagxwgm99.png" alt="Baboon" width="799" height="276"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;5. Splash&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MSE:&lt;/strong&gt; 1.9156&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PSNR:&lt;/strong&gt; 45.31 dB&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc026we3qm73vlyepzujl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc026we3qm73vlyepzujl.png" alt="Splash" width="799" height="276"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;6. Peppers&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MSE:&lt;/strong&gt; 7.5769&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PSNR:&lt;/strong&gt; 39.34 dB&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07lrotku5vbd5jr4si9c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F07lrotku5vbd5jr4si9c.png" alt="Peppers" width="799" height="276"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Training Convergence
&lt;/h3&gt;

&lt;p&gt;The training curve shows the stabilization of the Bayesian loss across the 200 epochs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpmcrayuse51eeonhbbc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpmcrayuse51eeonhbbc.png" alt="Training Convergence" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The loss function descends smoothly without exploding gradients, indicating that the model successfully learns to predict pixel values while accurately estimating its uncertainty bounds. 📉&lt;/p&gt;




&lt;h2&gt;
  
  
  🏁 Conclusion
&lt;/h2&gt;

&lt;p&gt;Reversible steganography is a fascinating intersection of deep learning and cryptography. By combining Bayesian uncertainty with clever modular arithmetic, we can achieve high-capacity hiding with zero data loss. 🛡️&lt;/p&gt;

&lt;p&gt;Check out the repository here: &lt;a href="https://github.com/Anjasfedo/bayesian_neural_network_reversible_steganography" rel="noopener noreferrer"&gt;Anjasfedo/bayesian_neural_network_reversible_steganography&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repository is structured cleanly in PyTorch, allowing you to train the network on your own datasets and test the limits of reversible embedding. 💻&lt;/p&gt;

&lt;p&gt;Have you ever worked with Bayesian Networks for tasks outside of standard classification? Let me know in the comments! 👇&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>steganography</category>
      <category>cybersecurity</category>
      <category>researchtocode</category>
    </item>
    <item>
      <title>Hiding in the Bits: Mastering AMBTC Steganography with Combination Theory</title>
      <dc:creator>Anjasfedo</dc:creator>
      <pubDate>Sun, 17 May 2026 04:56:55 +0000</pubDate>
      <link>https://dev.to/anjasfedo/hiding-in-the-bits-mastering-ambtc-steganography-with-combination-theory-12no</link>
      <guid>https://dev.to/anjasfedo/hiding-in-the-bits-mastering-ambtc-steganography-with-combination-theory-12no</guid>
      <description>&lt;p&gt;In our previous explorations, we looked at &lt;a href="https://dev.to/anjasfedo/hiding-in-plain-sight-building-coverless-steganography-cihmsb-with-python-1cj6"&gt;Coverless Steganography&lt;/a&gt;—a method where we don't change a single pixel, but instead find images that already "look" like our data.&lt;/p&gt;

&lt;p&gt;Today, we are shifting gears into the &lt;strong&gt;Compressed Domain&lt;/strong&gt;. We are going to hide secret messages inside the mathematics of image compression: &lt;strong&gt;Absolute Moment Block Truncation Coding (AMBTC)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, simple bit-swapping in a compressed file often leaves messy visual artifacts. This is why we add &lt;strong&gt;Combination Theory&lt;/strong&gt;. By using a pseudo-random Matrix P to map our message to a block's parity, we can hide 4 bits of data by flipping at most one single bit. This allows us to achieve high capacity while keeping the changes virtually invisible to the human eye.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Academic Attribution 📚&lt;/strong&gt;&lt;br&gt;
This implementation is based on the 2023 research paper:&lt;br&gt;
&lt;strong&gt;"High Imperceptible Data Hiding Method for AMBTC Compressed Images Based on Combination Theory"&lt;/strong&gt; by Kurnia Anggriani, Shu-Fen Chiou, Nan-I Wu, and Min-Shiang Hwang.&lt;br&gt;
DOI: &lt;a href="https://doi.org/10.20944/preprints202304.0341.v1" rel="noopener noreferrer"&gt;10.20944/preprints202304.0341.v1&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🖼️ What is AMBTC?
&lt;/h2&gt;

&lt;p&gt;Before we hide data, we have to compress the image. AMBTC works by dividing an image into 4x4 blocks. For each block, it calculates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;High Quantizer (hq):&lt;/strong&gt; The average value of "bright" pixels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low Quantizer (lq):&lt;/strong&gt; The average value of "dark" pixels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bitmap:&lt;/strong&gt; A 16-bit grid of 0s and 1s telling the computer which pixel gets which color.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This reduces a 16-pixel block (128 bits) down to just two 8-bit values and a 16-bit map (32 bits). It’s efficient, fast, and—most importantly—the perfect place to hide secrets.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎲 The Secret Sauce: Combination Theory
&lt;/h2&gt;

&lt;p&gt;The "magic" happens in the bitmap. Standard steganography might just flip bits randomly, but that creates "salt and pepper" noise that's easy to spot. Combination Theory uses a &lt;strong&gt;Pseudo-Random Matrix P&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate Matrix P:&lt;/strong&gt; Using a secret &lt;strong&gt;Seed&lt;/strong&gt; (our key), we create a 4x4 matrix filled with numbers 0–15 in a random order.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calculate Parity:&lt;/strong&gt; We look at the current bitmap and check the "features" based on Matrix P.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Flip:&lt;/strong&gt; If the parity doesn't match our secret message bits, we flip &lt;strong&gt;exactly one bit&lt;/strong&gt; in the bitmap.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0xgo4jkmpmg9uzo1ibz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0xgo4jkmpmg9uzo1ibz.png" alt="Result Comparison" width="800" height="277"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Because we only change one pixel in a 16-pixel block, the human eye (and even most statistical tools) can't tell anything has changed.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Benchmark: Performance Results
&lt;/h2&gt;

&lt;p&gt;I tested this "Base Implementation" on several standard 512x512 grayscale images. Each image was embedded with a full payload of &lt;strong&gt;65,536 bits&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Image&lt;/th&gt;
&lt;th&gt;MSE&lt;/th&gt;
&lt;th&gt;PSNR (dB)&lt;/th&gt;
&lt;th&gt;Capacity&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Splash&lt;/td&gt;
&lt;td&gt;14.6467&lt;/td&gt;
&lt;td&gt;36.4734&lt;/td&gt;
&lt;td&gt;65,536 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lena&lt;/td&gt;
&lt;td&gt;33.3143&lt;/td&gt;
&lt;td&gt;32.9045&lt;/td&gt;
&lt;td&gt;65,536 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Peppers&lt;/td&gt;
&lt;td&gt;34.9454&lt;/td&gt;
&lt;td&gt;32.6969&lt;/td&gt;
&lt;td&gt;65,536 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Airplane&lt;/td&gt;
&lt;td&gt;44.6739&lt;/td&gt;
&lt;td&gt;31.6303&lt;/td&gt;
&lt;td&gt;65,536 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sailboat&lt;/td&gt;
&lt;td&gt;76.0594&lt;/td&gt;
&lt;td&gt;29.3193&lt;/td&gt;
&lt;td&gt;65,536 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Baboon&lt;/td&gt;
&lt;td&gt;142.7971&lt;/td&gt;
&lt;td&gt;26.5836&lt;/td&gt;
&lt;td&gt;65,536 bits&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Observations:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Complexity Trade-off:&lt;/strong&gt; Images with smooth surfaces (like &lt;em&gt;Splash&lt;/em&gt;) achieve a much higher PSNR. Complex textures (like &lt;em&gt;Baboon&lt;/em&gt;'s fur) are harder to compress via AMBTC, which naturally lowers the baseline quality.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capacity is King:&lt;/strong&gt; Regardless of the image, we maintained a rock-solid capacity of &lt;strong&gt;65,536 bits&lt;/strong&gt;. This is far superior to most basic LSB methods when considering the file size.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔍 Why Hide in the Compressed Domain?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Smaller Footprint:&lt;/strong&gt; You aren't sending a massive raw PNG; you're sending compressed data that already looks "efficient."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bit-Level Security:&lt;/strong&gt; Without the correct &lt;strong&gt;Seed&lt;/strong&gt;, Matrix P is impossible to reconstruct. An attacker might see the modified bitmap, but they won't know which bits represent the message and which are just image data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Minimal Distortion:&lt;/strong&gt; Since we only flip a maximum of 1 bit per block, the visual integrity remains nearly perfect.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;AMBTC with Combination Theory represents a sophisticated balance between compression and secrecy. It proves that we don't need to choose between a small file size and a large hidden message—we can have both.&lt;/p&gt;

&lt;p&gt;If you want to dive into the code, check out the full Python implementation (including the performance test suite) on my GitHub:&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;&lt;a href="https://github.com/Anjasfedo/ambtc_ct_steganography" rel="noopener noreferrer"&gt;GitHub Repository: AMBTC Steganography&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What do you think? Is compressed-domain steganography the future, or do you prefer the "zero-touch" approach of coverless methods?&lt;/p&gt;

</description>
      <category>python</category>
      <category>cybersecurity</category>
      <category>steganography</category>
      <category>researchtocode</category>
    </item>
    <item>
      <title>Hidden in Plain Sight: Implementing StegoPNet for Deep Image Steganography 🚀</title>
      <dc:creator>Anjasfedo</dc:creator>
      <pubDate>Sat, 16 May 2026 04:51:33 +0000</pubDate>
      <link>https://dev.to/anjasfedo/hidden-in-plain-sight-implementing-stegopnet-for-deep-image-steganography-2k8o</link>
      <guid>https://dev.to/anjasfedo/hidden-in-plain-sight-implementing-stegopnet-for-deep-image-steganography-2k8o</guid>
      <description>&lt;p&gt;Imagine being able to hide a high-resolution photo of a baboon inside a photo of Lena, where the resulting image looks absolutely identical to the original to the naked eye. This isn't just a classic spy trope; it is a complex Deep Learning challenge. 🧬&lt;/p&gt;

&lt;p&gt;In this article, I will walk through my implementation and evaluation of StegoPNet, a research-backed architecture that uses Pyramid Pooling to achieve high-capacity image steganography.&lt;/p&gt;




&lt;h2&gt;
  
  
  📜 Academic Attribution
&lt;/h2&gt;

&lt;p&gt;First and foremost, this work is an implementation and exploration of the research paper:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"StegoPNet: Image Steganography With Generalization Ability Based on Pyramid Pooling Module"&lt;br&gt;
Authors: X. Duan, K. Jia, B. Li, D. Guo, Z. Zhang, and E. Sun&lt;br&gt;
Journal: IEEE Access, 2020&lt;br&gt;
DOI: &lt;a href="https://doi.org/10.1109/ACCESS.2020.3033895" rel="noopener noreferrer"&gt;10.1109/ACCESS.2020.3033895&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;All architectural foundations, specifically the integration of the Pyramid Pooling Module (PPM) for multi-scale feature extraction, are attributed to the original authors.&lt;/p&gt;




&lt;h2&gt;
  
  
  📌 The Challenge: High-Capacity Hiding
&lt;/h2&gt;

&lt;p&gt;Most traditional steganography methods hide tiny amounts of data, like text or small watermarks. StegoPNet aims for a 1:1 ratio: hiding a full-sized 256 x 256 RGB secret image inside a 256 x 256 RGB cover image. 🖼️&lt;/p&gt;

&lt;p&gt;Standard CNNs often struggle with this because they process images locally. When you hide a high-entropy image (like a Baboon with complex textures) inside a smooth image (like Lena's face), a standard CNN often leaves visible ghosts or artifacts.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧬 Why Pyramid Pooling?
&lt;/h2&gt;

&lt;p&gt;The core innovation here is the Pyramid Pooling Module (PPM). Unlike standard layers that focus on small pixel neighborhoods, the PPM captures features at five different scales (32 x 32 down to 2 x 2).&lt;/p&gt;

&lt;p&gt;By understanding the global context of the image, the network can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identify high-texture areas (like hair or fabric) where changes are harder to see. 🕵️&lt;/li&gt;
&lt;li&gt;Spread the secret data across different frequency bands to avoid statistical anomalies.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🧮 The Mathematical Framework
&lt;/h2&gt;

&lt;p&gt;The system optimizes a weighted Mean Squared Error (MSE) to balance invisibility with reconstruction accuracy:&lt;/p&gt;

&lt;p&gt;$$Loss = L_{h} + \alpha L_{r}$$&lt;/p&gt;

&lt;p&gt;Where $L_{h}$ is the Hiding Loss, $L_{r}$ is the Reveal Loss, and alpha is set to 0.6. This ensures the model prioritizes making the cover look clean while still allowing for perfect secret extraction. ⚖️&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Experimental Results (The Trial Run)
&lt;/h2&gt;

&lt;p&gt;I conducted a trial run using a Tesla T4 GPU on Google Colab, training the models on the classic Lena and Baboon pair for 3,000 iterations.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Visual Performance &amp;amp; Error Analysis
&lt;/h3&gt;

&lt;p&gt;When we look at the Error Maps (the pixel difference between original and stego multiplied by 10), the difference is staggering.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsz5g1014z03txif6kx35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsz5g1014z03txif6kx35.png" alt="Visual Performance &amp;amp; Error Analysis" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;No PPM (Baseline): Shows noticeable distortion. The error is scattered and creates hotspots that are easy for steganalysis tools to detect.&lt;/li&gt;
&lt;li&gt;With PPM (Proposed): The stego image is visually indistinguishable. The error is intelligently concentrated in textured areas, significantly improving imperceptibility. 🌈&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Training Convergence
&lt;/h3&gt;

&lt;p&gt;The training curves show how much more stable the PPM architecture is compared to a standard baseline.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8h534b2vs2mfhydyywd5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8h534b2vs2mfhydyywd5.png" alt="Training Convergence" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;PPM (Orange): Exhibits a smoother, faster descent. It achieves a much lower loss, proving it solves the hiding/revealing task more effectively.&lt;/li&gt;
&lt;li&gt;No PPM (Blue): Displayed high volatility and sharp spikes, indicating the network struggled to pack high-entropy data without ruining the cover image. 📉&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏁 Conclusion
&lt;/h2&gt;

&lt;p&gt;Global context matters in image steganography. By using multi-scale features, StegoPNet proves that we can achieve massive payload capacity without sacrificing security. 🛡️&lt;/p&gt;

&lt;p&gt;Check out the full repository here: [&lt;a href="https://github.com/Anjasfedo/stegopnet" rel="noopener noreferrer"&gt;https://github.com/Anjasfedo/stegopnet&lt;/a&gt;]&lt;br&gt;
The repository is structured to allow for easy ablation studies, so you can test exactly what happens when you toggle the PPM module on or off. 💻&lt;/p&gt;

&lt;p&gt;Do you think Deep Learning will eventually make traditional statistical steganalysis obsolete? Let me know in the comments! 👇&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>steganography</category>
      <category>computerscience</category>
      <category>researchtocode</category>
    </item>
    <item>
      <title>Scaling Stealth: Massive Capacity Upgrades for Coverless Steganography with E-CIHMSB and CB-CIHMSB 🕵️‍♂️📈</title>
      <dc:creator>Anjasfedo</dc:creator>
      <pubDate>Sat, 16 May 2026 04:11:03 +0000</pubDate>
      <link>https://dev.to/anjasfedo/scaling-stealth-massive-capacity-upgrades-for-coverless-steganography-with-e-cihmsb-and-cb-cihmsb-5afk</link>
      <guid>https://dev.to/anjasfedo/scaling-stealth-massive-capacity-upgrades-for-coverless-steganography-with-e-cihmsb-and-cb-cihmsb-5afk</guid>
      <description>&lt;p&gt;In our journey through coverless steganography, we first explored &lt;a href="https://dev.to/anjasfedo/hiding-in-plain-sight-building-coverless-steganography-cihmsb-with-python-1cj6"&gt;CIHMSB &lt;/a&gt;—a method that hides data by matching message bits to the average intensity of image fragments. While perfect in its invisibility, CIHMSB faces a significant hurdle: capacity. Using only one bit per fragment limits how much data we can hide in a single image.&lt;/p&gt;

&lt;p&gt;Today, we are looking at two advanced extensions that shatter these capacity limits: E-CIHMSB and CB-CIHMSB. By applying matrix extensions and combination theory, we can pack significantly more data into the same carrier while actually improving robustness against image attacks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Academic Attribution 📚&lt;br&gt;
This implementation and analysis are based on the 2023 research paper:&lt;br&gt;
"A Robust and High-Capacity Coverless Information Hiding Based on Combination Theory" by Kurnia Anggriani, Shu-Fen Chiou, Nan-I Wu, and Min-Shiang Hwang.&lt;br&gt;
DOI: &lt;a href="https://doi.org/10.15388/23-INFOR521" rel="noopener noreferrer"&gt;https://doi.org/10.15388/23-INFOR521&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🚀 The Next Evolution: Two Powerful Extensions
&lt;/h2&gt;

&lt;p&gt;The researchers identified that the original CIHMSB only embeds one bit per segment, making it inefficient for large messages. They proposed two solutions:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. E-CIHMSB (Extended CIHMSB)
&lt;/h3&gt;

&lt;p&gt;This scheme builds an "Extended Matrix". After calculating the average pixel values for all fragments in a group, it adds one extra value: the average of all those averages. This simple mathematical addition increases the bit pool for every image carrier.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. CB-CIHMSB (Combination Theory-Based)
&lt;/h3&gt;

&lt;p&gt;This is the true heavy-lifter. Instead of just adding one value, it uses combination theory to create a "Combined Matrix". If you have a group of n fragments, it calculates the averages for every possible combination of those fragments (choosing 1, 2, 3, or all n).&lt;br&gt;
The capacity growth is exponential: EC = 2^n - 1. For a group of 4 fragments, you generate 15 feature values instead of just 4!&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Benchmark: Performance Comparison
&lt;/h2&gt;

&lt;p&gt;To see these algorithms in action, I ran a full experimental benchmark on a 512x512 carrier image using 8x8 fragments. Here are the real-world results:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Image Quality Assessment
&lt;/h3&gt;

&lt;p&gt;As these are coverless methods, the image itself is never modified.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SSIM: 1.0 (Perfect match) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Qi: 1.0 (Optimal quality) &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Hiding Capacity (512x512 Carrier)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Bits per Carrier&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Original CIHMSB&lt;/td&gt;
&lt;td&gt;16,384 bits&lt;/td&gt;
&lt;td&gt;Baseline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;E-CIHMSB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;20,480 bits&lt;/td&gt;
&lt;td&gt;+25%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CB-CIHMSB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;61,440 bits&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;+275%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  3. Robustness Analysis (BER)
&lt;/h3&gt;

&lt;p&gt;Bit Error Rate (BER) measures how many bits were lost during a transmission attack. Lower is better.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attack Type&lt;/th&gt;
&lt;th&gt;E-CIHMSB BER&lt;/th&gt;
&lt;th&gt;CB-CIHMSB BER&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AGWN (Var 0.1)&lt;/td&gt;
&lt;td&gt;16.07%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;7.14%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SPN (Dens 0.005)&lt;/td&gt;
&lt;td&gt;5.36%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.79%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AF (3x3 Window)&lt;/td&gt;
&lt;td&gt;12.50%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8.93%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;JPEG (Quality 50-90)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1.79% - 5.36%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.00% (Perfect)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🔍 Why is CB-CIHMSB the Clear Winner?
&lt;/h2&gt;

&lt;p&gt;Looking at the benchmark data, CB-CIHMSB is superior for two main reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Massive Capacity: It offers 275% more capacity than the original method. You can hide an entire secret document where you previously could only hide a short paragraph.&lt;/li&gt;
&lt;li&gt;Superior Robustness: Notice the JPEG compression results. While E-CIHMSB suffered some errors, CB-CIHMSB achieved a 0.00% Bit Error Rate. Because it averages multiple combinations of fragments, the secret features become more "stable" and resistant to pixel-level distortions like JPEG artifacts or blurring.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;The research by Anggriani et al. proves that coverless steganography does not have to be low-capacity. By shifting from linear fragment matching to combinatorial logic, we can hide massive amounts of data with zero pixel manipulation. This makes it impossible for standard steganalysis tools to detect anything—because mathematically, there is nothing "embedded" in the pixels.&lt;/p&gt;

&lt;p&gt;Check out the full modular Python implementation on my GitHub! &lt;a href="https://github.com/Anjasfedo/ecihmsb_cbcihmsb" rel="noopener noreferrer"&gt;https://github.com/Anjasfedo/ecihmsb_cbcihmsb&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>cybersecurity</category>
      <category>steganography</category>
      <category>researchtocode</category>
    </item>
    <item>
      <title>Tripling Data Capacity: Implementing CIHLHF Coverless Steganography in Python 🕵️‍♂️🚀</title>
      <dc:creator>Anjasfedo</dc:creator>
      <pubDate>Sat, 16 May 2026 03:26:12 +0000</pubDate>
      <link>https://dev.to/anjasfedo/tripling-data-capacity-implementing-cihlhf-coverless-steganography-in-python-kn7</link>
      <guid>https://dev.to/anjasfedo/tripling-data-capacity-implementing-cihlhf-coverless-steganography-in-python-kn7</guid>
      <description>&lt;p&gt;In my previous post, we explored &lt;a href="https://dev.to/anjasfedo/hiding-in-plain-sight-building-coverless-steganography-cihmsb-with-python-1cj6"&gt;&lt;strong&gt;CIHMSB&lt;/strong&gt;&lt;/a&gt;, a way to hide data in images without changing a single pixel by using the average value of image fragments. While it offers perfect invisibility, the main challenge is &lt;strong&gt;hiding capacity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Today, we are looking at the next evolution: &lt;strong&gt;CIHLHF&lt;/strong&gt;. By targeting the "Extremes"—the lowest and highest pixel values in a fragment—we can pack &lt;strong&gt;three times more information&lt;/strong&gt; into the same image while maintaining uncrackable security.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Academic Attribution 📚&lt;/strong&gt;&lt;br&gt;
This article is based on the 2023 research paper:&lt;br&gt;
&lt;em&gt;"A High-Capacity Coverless Information Hiding Based on the Lowest and Highest Image Fragments"&lt;/em&gt; by Kurnia Anggriani, Shu-Fen Chiou, Nan-I Wu, and Min-Shiang Hwang.&lt;br&gt;
Published in &lt;em&gt;Electronics 2023, 12, 395&lt;/em&gt;.&lt;br&gt;
&lt;a href="https://doi.org/10.3390/electronics12020395" rel="noopener noreferrer"&gt;DOI: 10.3390/electronics12020395&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It also references the foundational CIHMSB method:&lt;br&gt;
&lt;em&gt;"A Novel Coverless Information Hiding Method Based on the Most Significant Bit of the Cover Image"&lt;/em&gt; by Lina Yang, Haiyu Deng, and Xiaocui Dang (IEEE Access, 2020).&lt;br&gt;
&lt;a href="http://doi.org/10.1109/ACCESS.2020.3000993" rel="noopener noreferrer"&gt;DOI: 10.1109/ACCESS.2020.3000993&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧠 Why CIHLHF?
&lt;/h2&gt;

&lt;p&gt;The original CIHMSB method maps bits to the &lt;strong&gt;Average Intensity&lt;/strong&gt; of a fragment. CIHLHF introduces two major upgrades:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Dual-Value Mapping:&lt;/strong&gt; Instead of a single average, it extracts the &lt;strong&gt;Minimum (L)&lt;/strong&gt; and &lt;strong&gt;Maximum (H)&lt;/strong&gt; values from each fragment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Increased Payload:&lt;/strong&gt; By extracting multiple MSB bits from both the &lt;code&gt;L&lt;/code&gt; and &lt;code&gt;H&lt;/code&gt; values, the total bit pool per image is significantly larger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Z-Key (Secret Mapping):&lt;/strong&gt; Both the sender and receiver use a shared secret key (&lt;code&gt;Z&lt;/code&gt;) to randomize the fragment sequence, ensuring that even if an attacker intercepts the image, the data remains scrambled.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Like its predecessor, it remains &lt;strong&gt;Coverless&lt;/strong&gt;, meaning the stego image is identical to the cover image.&lt;/p&gt;




&lt;h2&gt;
  
  
  💻 The Implementation
&lt;/h2&gt;

&lt;p&gt;This Python implementation handles the extraction of extreme values and the random Z-key permutation logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CIHLHF&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;first_msb_bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;second_msb_bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fragment_size&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first_msb_bits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;first_msb_bits&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;second_msb_bits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;second_msb_bits&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;seed&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_text_to_bin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;binary_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;bin_char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;char&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;07b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;bit&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;bin_char&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;binary_list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;binary_list&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_bin_to_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;binary_list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binary_list&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;binary_list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;
            &lt;span class="n"&gt;chunk_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_extract_min_max_msbs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
        &lt;span class="n"&gt;h_trunc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;w_trunc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;msb_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h_trunc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w_trunc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;fragment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="n"&gt;min_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fragment&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 
                &lt;span class="n"&gt;max_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fragment&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 

                &lt;span class="n"&gt;bin_min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min_val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;08b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;first_msb_bits&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="n"&gt;msb_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bin_min&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;

                &lt;span class="n"&gt;bin_max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;08b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;second_msb_bits&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="n"&gt;msb_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bin_max&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;msb_pool&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_generate_z_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;capacity&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;capacity&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_state&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;z_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;permutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;arange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;capacity&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;z_key&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tolist&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;embed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret_text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;secret_bits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_text_to_bin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;msb_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_extract_min_max_msbs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_bits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msb_pool&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Capacity &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msb_pool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; bits is not enough.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;z_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_generate_z_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msb_pool&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;mapping_flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_bits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_bits&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="n"&gt;target_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;z_key&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="n"&gt;mapping_flag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;secret_bits&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;msb_pool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;target_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mapping_flag&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mapping_flag&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;msb_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_extract_min_max_msbs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;z_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_generate_z_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msb_pool&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;secret_bits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mapping_flag&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
            &lt;span class="n"&gt;target_index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;z_key&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
            &lt;span class="n"&gt;t_i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;mapping_flag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;msb_pool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;target_index&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
            &lt;span class="n"&gt;secret_bits&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_bin_to_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_bits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧪 Replicating the Paper: Benchmark Results
&lt;/h2&gt;

&lt;p&gt;To verify the effectiveness of CIHLHF, I ran a full replication suite based on the experiments conducted by Anggriani et al. Here are the results from the Python test suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1] CIHLHF EXPERIMENT DEMO
Original Message: CIHLHF_REPLICATION_2026
Extraction Match: True

[2] HIDING CAPACITY ANALYSIS
Total Fragments   : 4096
CIHMSB Capacity   : 16384 bits
CIHLHF Capacity   : 49152 bits
Improvement Factor: 3.0x

[3] SECURITY ANALYSIS (Brute-Force Complexity)
Total Fragments (Ci) : 4096
Secret Bits (Ti)     : 49152
Complexity (Years)   : 2.69 x 10^209255

[4] IMAGE QUALITY ASSESSMENT (IQA)
MSE  : 0.0
PSNR : inf dB
SSIM : 1.0
Qi   : 1.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Analysis of Results:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;3.0x Capacity Leap:&lt;/strong&gt; By utilizing 12 bits per fragment (6 from the minimum value and 6 from the maximum), the capacity jumps from 16,384 bits to a massive &lt;strong&gt;49,152 bits&lt;/strong&gt; for a 512 x 512 carrier image.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Optimal Visual Quality:&lt;/strong&gt; Since no pixels are modified, the &lt;strong&gt;PSNR remains infinite&lt;/strong&gt; and the &lt;strong&gt;SSIM is a perfect 1.0&lt;/strong&gt;. The image is mathematically identical to the original.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Extreme Security:&lt;/strong&gt; The brute-force complexity for a 512x512 image reaches an astronomical &lt;strong&gt;10^209255 combinations&lt;/strong&gt;, making it physically impossible to crack without the secret mapping key &lt;code&gt;Z&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;CIHLHF proves that we don't have to sacrifice capacity for security. By shifting the mapping logic from the fragment's average value to its extreme values, we can hide massive amounts of data in plain sight—unseen by both the human eye and digital steganalysis tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source code and replication scripts are available on my GitHub! ⭐&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Anjasfedo/cihlhf" rel="noopener noreferrer"&gt;https://github.com/Anjasfedo/cihlhf&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>cybersecurity</category>
      <category>steganography</category>
      <category>researchtocode</category>
    </item>
    <item>
      <title>Hiding in Plain Sight: Building Coverless Steganography (CIHMSB) with Python 🕵️‍♂️🐍</title>
      <dc:creator>Anjasfedo</dc:creator>
      <pubDate>Fri, 15 May 2026 18:06:00 +0000</pubDate>
      <link>https://dev.to/anjasfedo/hiding-in-plain-sight-building-coverless-steganography-cihmsb-with-python-1cj6</link>
      <guid>https://dev.to/anjasfedo/hiding-in-plain-sight-building-coverless-steganography-cihmsb-with-python-1cj6</guid>
      <description>&lt;p&gt;If you have ever explored cybersecurity, you probably know about Steganography—the art of hiding secret messages inside an image.&lt;/p&gt;

&lt;p&gt;The most popular approach is usually the LSB (Least Significant Bit) method, where we slightly alter the pixel colors to embed text. The problem? Modern detection tools (steganalysis) are incredibly smart. Altering even a single bit can trigger an alert that the image has been manipulated.&lt;/p&gt;

&lt;p&gt;So, what if we could hide data without changing a single pixel of the original image?&lt;/p&gt;

&lt;p&gt;Welcome to the world of Coverless Steganography.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Academic Attribution 📚&lt;/strong&gt;&lt;br&gt;
The article and code below are the result of my independent breakdown and implementation based on an excellent academic paper titled:&lt;br&gt;
&lt;em&gt;"A Novel Coverless Information Hiding Method Based on the Most Significant Bit of the Cover Image"&lt;/em&gt; by Lina Yang, Haiyu Deng, and Xiaocui Dang (IEEE Access, 2020).&lt;br&gt;
&lt;a href="http://doi.org/10.1109/ACCESS.2020.3000993" rel="noopener noreferrer"&gt;DOI: 10.1109/ACCESS.2020.3000993&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let us break down how it works and write the code in Python!&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 Core Concept of CIHMSB
&lt;/h2&gt;

&lt;p&gt;CIHMSB stands for &lt;em&gt;Coverless Information Hiding Method based on Most Significant Bit&lt;/em&gt;. It relies on logic matching rather than physical embedding. Here is the simple workflow based on the original paper:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Convert Message to Binary:&lt;/strong&gt; Change your secret message into a sequence of &lt;code&gt;0&lt;/code&gt;s and &lt;code&gt;1&lt;/code&gt;s using a 7-bit ASCII format.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Divide the Image:&lt;/strong&gt; Cut the original grayscale image matrix into small grids or fragments, for example, 8x8 or 5x5 pixels.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calculate Average and Extract MSB:&lt;/strong&gt; Instead of looking at a single random pixel, calculate the average pixel value of the entire fragment. Then, extract the Most Significant Bits from that average value.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Magic Matching:&lt;/strong&gt; Compare your message bits with the extracted image MSBs. If they match, we record a &lt;code&gt;1&lt;/code&gt; in a separate ledger. If they do not match, we record a &lt;code&gt;0&lt;/code&gt;. This ledger is called the &lt;strong&gt;Mapping Flag&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transmission:&lt;/strong&gt; You send the &lt;strong&gt;100% unaltered original image&lt;/strong&gt; and the Mapping Flag file to your receiver.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because the original image is completely untouched, error detection metrics return an Infinite value. Zero pixels are damaged!&lt;/p&gt;




&lt;h2&gt;
  
  
  💻 Let's Write the Code
&lt;/h2&gt;

&lt;p&gt;We will use the &lt;code&gt;numpy&lt;/code&gt; library to manipulate the image matrices. Notice how the class allows us to extract multiple MSB bits per fragment to increase the hiding capacity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CIHMSB&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msb_bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fragment_size&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;msb_bits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;msb_bits&lt;/span&gt; 

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_text_to_bin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;binary_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;char&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;bin_char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;ord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;char&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;07b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;bit&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;bin_char&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;binary_list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bit&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;binary_list&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_bin_to_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;binary_list&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binary_list&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;binary_list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;
            &lt;span class="n"&gt;chunk_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nf"&gt;chr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_extract_image_msb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;
        &lt;span class="n"&gt;h_trunc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;w_trunc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;msb_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h_trunc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;w_trunc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="n"&gt;fragment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
                &lt;span class="n"&gt;avg_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fragment&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

                &lt;span class="n"&gt;bin_avg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;avg_val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;08b&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;msb_bits&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                    &lt;span class="n"&gt;msb_pool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bin_avg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;msb_pool&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;embed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret_text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;secret_bits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_text_to_bin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;msb_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_extract_image_msb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_bits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msb_pool&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Kapasitas tidak cukup.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;secret_bits&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;msb_pool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_bits&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mapping_flag&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;msb_pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_extract_image_msb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image_array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;secret_bits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;mapping_flag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;msb_pool&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mapping_flag&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_bin_to_text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret_bits&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to Run It
&lt;/h3&gt;

&lt;p&gt;Now, let us test the code above. You will need a grayscale image loaded into a numpy array (named &lt;code&gt;img_array&lt;/code&gt; in this example). We will configure it to use 4 bits per fragment to simulate a high-capacity scenario.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;img_pil&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;assets/cover.png&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;L&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;img_array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img_pil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;cihmsb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CIHMSB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fragment_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msb_bits&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;secret_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SECRET MESSAGE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Original Message: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;secret_message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;mapping_flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cihmsb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;embed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img_array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret_message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Transmitted Mapping Flag: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;mapping_flag&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;... (Total &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mapping_flag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; bits)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;extracted_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cihmsb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;img_array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mapping_flag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Extracted Message: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;extracted_message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧪 Replicating the Paper's Experiments
&lt;/h2&gt;

&lt;p&gt;To prove that this method works exactly as the IEEE paper claims, I built a complete test suite to replicate their Image Quality Assessment (IQA), Security Analysis, and Robustness parameters.&lt;/p&gt;

&lt;p&gt;Here is the terminal output from running the master test script on a 256x256 image with 5x5 fragments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1] EXPERIMENT DEMO
Secret message length : 160 characters
Binary bit length     : 1120 bits
Extraction Match      : True

[2] HIDING CAPACITY ANALYSIS
Image Size          : 256x256
Fragment Size       : 5x5
Max Hiding Capacity : 2601 bits per carrier

[3] SECURITY ANALYSIS (Violent Attack)
Total Image Fragments (Fm) : 2601
Secret Bits (Cn)           : 1120
Possible Attack Combos (U) : 10^3701 combinations

[4] IMAGE QUALITY ASSESSMENT (IQA)
Mean Square Error (MSE) : 0.0
PSNR (dB)               : inf
SSIM                    : 1.0
Universal Quality (Qi)  : 1.0

[5] ROBUSTNESS ANALYSIS: AWGN &amp;amp; JPEG
--- AWGN (Gaussian Noise) ---
Variance 0.1 -&amp;gt; BER: 9.73%
Variance 0.5 -&amp;gt; BER: 33.04%
Variance 1.0 -&amp;gt; BER: 45.36%

--- JPEG Compression ---
Quality 90   -&amp;gt; BER: 1.16%
Quality 70   -&amp;gt; BER: 1.96%
Quality 50   -&amp;gt; BER: 3.12%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Takeaways from the Benchmark:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Perfect Image Quality:&lt;/strong&gt; Notice the PSNR is &lt;code&gt;inf&lt;/code&gt; (Infinite) and SSIM is &lt;code&gt;1.0&lt;/code&gt;. Because we don't manipulate pixels, the stego image is mathematically identical to the cover image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unbreakable Brute-Force:&lt;/strong&gt; Without the Mapping Flag, an attacker trying a violent brute-force attack would face &lt;code&gt;10^3701&lt;/code&gt; combinations to extract just 1120 bits.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Robustness:&lt;/strong&gt; Even if the image is compressed and loses quality (JPEG Quality 50), the Bit Error Rate (BER) remains remarkably low at just &lt;code&gt;3.12%&lt;/code&gt;, meaning most of the secret text is still perfectly readable!&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🎯 Conclusion
&lt;/h2&gt;

&lt;p&gt;The main advantage of this Coverless method is: Your original image does not change at all. If a hacker or analyst intercepts the image and checks its MD5 hash or color histogram, they will find absolutely nothing suspicious. It is just a normal image.&lt;/p&gt;

&lt;p&gt;The secret data will only materialize if that specific original image is paired with the Mapping Flag file we send separately. By averaging the fragment values instead of picking a single pixel, this specific algorithm also ensures better robustness against minor image distortions like JPEG compression.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I have uploaded the full source code and the complete test replication suite to my GitHub repository. Feel free to check it out, run the tests yourself, and give it a star! ⭐&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/Anjasfedo/cihmsb" rel="noopener noreferrer"&gt;https://github.com/Anjasfedo/cihmsb&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What do you think? Will this zero-pixel manipulation method become the data security standard of the future? Let me know in the comments below!&lt;/p&gt;

</description>
      <category>python</category>
      <category>cybersecurity</category>
      <category>steganography</category>
      <category>researchtocode</category>
    </item>
  </channel>
</rss>
