
Pythonによるステガノグラフィ | 画像ファイルにファイルやデータを隠す
このスクリプトはファイルを画像内に隠し、変更された画像をディスクに保存します。
画像内に隠せるファイルの最大サイズは、画像の寸法に依存します。
max_file_size = ( height_of_image * width_of_image * 6 / 8 ) bytes
'100k words.txt' は 'original_image.png' に隠されており、'image_with_100k words.png' という名前で保存されています。 これら2つの画像の違いを見つけられるか確認してみてください。 このモジュールを使用して、'image_with_100k words.png' から '100k words.txt' を抽出できます。
元の画像

変更後の画像

この画像には10万語(テキストファイル)が隠されています!
これは、各ピクセルのLSB(最下位ビット)を変更しても、その変化は重要ではなく、目で気づかれないという単純な原理に基づいています。
したがって、このモジュールは隠すファイルから2ビットのデータを取り出し、1つのピクセルの最後の2ビットをその2ビットで置き換え、次のピクセルに移動します。 ピクセルの最大変化は4単位であり、PNG画像の値の範囲は(0,255)であるため、この変化は重要ではありません。
PNG画像では、各ピクセルは3つのチャンネル(赤、緑、青)を持ちます。(一部のPNG画像は1または4チャンネルですが、このプログラムはそれらを3チャンネルに変換します) PNG画像の典型的なピクセルは次のようになります:
a_pixel = (17,32,11) # (RED, GREEN, BLUE)
したがって、1ピクセルに3回×2ビット、つまり1ピクセルあたり6ビットを保存できます。これにより、画像に隠せるファイルサイズの上限が決まります:
max_file_size = ( height_of_image * width_of_image * 6 / 8 ) bytes
例を使って理解しましょう。隠すデータは次のとおりです:
binary_data = 0b100111
最初の2ビットを取り出し、'a_pixel'の赤チャンネルと置き換えます。
a_pixel = (0b10001, 0b100000, 0b1011) # binary representation of a_pixel values
# Let's change a_pixel's RED Channel
# 0b10001 -> 0b10010 ( First 2 bits are 10 )
a_pixel = (0b10010, 0b100000, 0b1011) # modified pixel
再びbinary_dataから2ビットを取り出し、緑チャンネルの最後の2ビットと置き換えます。
a_pixel = (0b10010, 0b100000, 0b1011)
# Let's change a_pixel's GREEN Channel
# 0b100000 -> 0b100001 ( The 2 bits are 01 )
a_pixel = (0b10010, 0b100001, 0b1011) # modified pixel
青チャンネルでもう一度これを行い、完了です。
a_pixel = (0b10010, 0b100001, 0b1011)
# Let's change a_pixel's BLUE Channel
# 0b1011 -> 0b1011 ( The 2 bits are 11 ) ; Notice that the value wasn't changed this time
a_pixel = (0b10010, 0b100001, 0b1011) # pixel wasn't modified this time
これで、6ビットのメッセージを1ピクセルに隠しました。ピクセルの変化を見てみましょう。
a_pixel = (0b10001, 0b100000, 0b1011) = (17, 32, 11)
a_pixel_with_data = (0b10010, 0b100001, 0b1011) = (18, 33, 11)
見てわかるように、変化はピクセルレベルでも気づかれません。モジュールはすべてのデータが画像に保存されるまでこれを繰り返します。

注意:写真のノイズが増加し、写真編集ソフトウェアを使用して元の画像と比較すると、この画像は元の画像よりもはるかにノイズが多くなります。
この問題の解決策:元の画像をインターネットにアップロード/共有しないこと
MIT
自由ソフトウェア、最高!