7

Stepic 0.3 を使用。メッセージを JPG 画像にエンコードするコマンドを実行しています。私が使用するコードは次のとおりです。

from PIL import Image
import stepic

im = Image.open ("tester.jpg")
im2 = stepic.encode(im, '0987639987069730979076409784690y7689734')
im2.save('stegtest.jpg')
im1 = Image.open('stegtest.jpg')
s = stepic.decode(im1) 
print s
data = s.decode() 
print data

それでも、印刷 S と印刷データは、次のような値を提供します: 6` またはその他の奇妙な文字。関数を本来の用途で使用していると思いますが、適切な結果が得られないのはなぜですか?

4

1 に答える 1

6

stepic 0.3 は、画像のステガノグラフィに対して最も単純なアプローチを使用します。モジュールから直接引用:

def decode_imdata(imdata):
    '''Given a sequence of pixels, returns an iterator of characters
    encoded in the image'''

    imdata = iter(imdata)
    while True:
        pixels = list(imdata.next()[:3] + imdata.next()[:3] + imdata.next()[:3])
        byte = 0
        for c in xrange(7):
            byte |= pixels[c] & 1
            byte <<= 1
        byte |= pixels[7] & 1
        yield chr(byte)
        if pixels[-1] & 1:
            break

秘密データのすべてのオクテットと、それが最後のバイトであるかどうかのフラグは、3 つの連続するピクセルに隠されています。より正確に言うと、stepic は各ピクセルの最初の 3 つのコンポーネント (通常は RGB) の最下位ビットを使用します。コンポーネントごとに 4 ビットの RGBA ストリームについては、この非常に醜い図を参照してください (DはデータをE意味し、ストリームの終わりを意味します)。

                   | pixel 0             | pixel 1             | pixel 2             |
image viewer sees: | rrrr gggg bbbb aaaa | rrrr gggg bbbb aaaa | rrrr gggg bbbb aaaa |
stepic sees:       | ___D ___D ___D ____ | ___D ___D ___D ____ | ___D ___D ___E ____ |

この変更によって導入されたノイズは、既に「ノイズが多い」画像 (256 分の 1) では小さいため、多くの場合、これを実際に視覚的に検出することはできません。これは、この手法の目的が達成されたことを意味します。自然に発生するノイズと誰も区別できないため、データは目に見えないところに隠されています。

これは機能します。少なくとも、PNG などのロスレス形式では機能します。残念ながら、JPG は無損失ではなく、その圧縮によってエンコードされたビットの少なくとも 1 つが変更される可能性が非常に高くなります。隠しデータが 1 バイトに切り捨てられるため、9 番目のビットを変更してこのメ​​ソッドをほとんど役に立たなくするだけで十分です。

JPG 画像のステガノグラフィーは多くの形式でまだ可能ですが、デコードされたピクセル値を微調整するだけでは十分ではありません。より良い (しかしより複雑な) 方法は、コンプレッサーによって推定されたパラメーターにデータを隠すことです。

于 2013-05-30T15:37:39.387 に答える