Blame view

msteg/steganography/F4-simple.py 3.2 KB
1d19f0e7   Chunk   staged.
1
2
3
4
5
6
7
8
9
10
11
12
13
__author__ = 'chunk'

"""
<p>This module implements a slight variant of the F4 steganography algorithm
invented by Andreas Westfeld. It embeds a secret message in JPEG
DCT coefficients.</p>
It differs from F3 in that even negative and odd positive DCT
coefficients represent a 1 and odd negative and even positive
DCT coefficients represent a 0. It also supports permutative strattling
which is not included in the original description of F4.
"""

import numpy as np
ca73c96f   Chunk   Transformed into ...
14
15
16

from .. import *
from ...common import *
1d19f0e7   Chunk   staged.
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102


class F4(StegBase):
    """ This module has two methods: <i>embed_raw_data</i> to embed data
    with the F3 algorithm and <i>extract_raw_data</i> to extract data
    which was embedded previously. """

    def __init__(self):
        """
        Constructor of the F3 class.
        """
        StegBase.__init__(self)

    def embed_raw_data(self, src_cover, src_hidden, tgt_stego):
        """ This method embeds arbitrary data into a cover image.
        The cover image must be a JPEG.

        src_cover - A valid pathname to an image file which serves as cover image
        (the image which the secret image is embedded into).

        src_hidden - A valid pathname to an arbitrary file that is supposed to be
        embedded into the cover image.

        tgt_stego - Target pathname of the resulting stego image. You should save to a
        PNG or another lossless format, because many LSBs don't survive
        lossy compression.
        """
        self.t0 = time.time()
        StegBase._post_embed_actions(self, src_cover, src_hidden, tgt_stego)

    def extract_raw_data(self, src_steg, tgt_hidden):
        """ This method extracts secret data from a stego image. It is
        (obviously) the inverse operation of embed_raw_data.

        src_stego - A valid pathname to an image file which serves as stego image.

        tgt_hidden - A pathname denoting where the extracted data should be saved to.
        """
        self.t0 = time.time()
        StegBase._post_extract_actions(self, src_steg, tgt_hidden)

    def _raw_embed(self, cov_data, hid_data, status_begin=0):
        """
        cov_data - 4-D numpy.int32 array
        hid_data - 1-D numpy.uint8 array
        """
        hid_data = bytes2bits(hid_data)
        i = 0
        cnt = -1
        for x in np.nditer(cov_data, op_flags=['readwrite']):
            cnt = cnt + 1
            if x == 0 or cnt % 64 == 0: continue

            m = (hid_data[i] & 1)
            if x > 0 and x & 1 != m:
                x[...] -= 1
            elif x < 0 and x & 1 == m:
                x[...] += 1
            if x == 0: continue
            i += 1
            if i == hid_data.size: break

        return cov_data

    def _raw_extract(self, steg_data, num_bits):
        """
        Just a small helper function to extract hidden data.
        """
        hid_data = np.zeros(num_bits, np.uint8)
        j = 0
        cnt = -1
        for x in np.nditer(steg_data):
            cnt = cnt + 1
            if x == 0 or cnt % 64 == 0: continue
            if j >= num_bits: break
            if x > 0:
                hid_data[j] = x & 1
            else:
                hid_data[j] = (x & 1) ^ 1

            j = j + 1

        return hid_data

    def __str__(self):
        return "F4'"