Blame view

msteg/steganography/F4.py 3.2 KB
6cbb3879   Chunk   F4 updated.
1
2
"""
<p>This module implements a slight variant of the F4 steganography algorithm
c9fdeb00   Chunk   LSB and F4 added.
3
invented by Andreas Westfeld. It embeds a secret message in JPEG
6cbb3879   Chunk   F4 updated.
4
DCT coefficients.</p>
b69b6985   Chunk   py module refract...
5
It differs from F3 in that even negative and odd positive DCT
c6c61f81   Chunk   staged.
6
coefficients represent a 1 and odd negative and even positive
c9fdeb00   Chunk   LSB and F4 added.
7
8
9
DCT coefficients represent a 0. It also supports permutative strattling
which is not included in the original description of F4.
"""
45a82355   Chunk   staged.
10
import time
c9fdeb00   Chunk   LSB and F4 added.
11
12
13
14
import numpy as np
from msteg.StegBase import StegBase
from common import *

6cbb3879   Chunk   F4 updated.
15

c9fdeb00   Chunk   LSB and F4 added.
16
17
18
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
033d3b0d   Chunk   staged.
19
    which was embedded previously. """
c9fdeb00   Chunk   LSB and F4 added.
20

6cbb3879   Chunk   F4 updated.
21
22
23
24
    def __init__(self):
        """
        Constructor of the F3 class.
        """
c6c61f81   Chunk   staged.
25
        StegBase.__init__(self)
c9fdeb00   Chunk   LSB and F4 added.
26

6cbb3879   Chunk   F4 updated.
27
28
29
    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.
c9fdeb00   Chunk   LSB and F4 added.
30

6cbb3879   Chunk   F4 updated.
31
        src_cover - A valid pathname to an image file which serves as cover image
c9fdeb00   Chunk   LSB and F4 added.
32
        (the image which the secret image is embedded into).
c9fdeb00   Chunk   LSB and F4 added.
33

c9fdeb00   Chunk   LSB and F4 added.
34
        src_hidden - A valid pathname to an arbitrary file that is supposed to be
6cbb3879   Chunk   F4 updated.
35
36
37
38
        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
c9fdeb00   Chunk   LSB and F4 added.
39
        lossy compression.
6cbb3879   Chunk   F4 updated.
40
41
42
43
44
45
46
47
48
        """
        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.
873557f9   Chunk   staged.
49
50
51
52
53
54
55
56
57

        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
6cbb3879   Chunk   F4 updated.
58
59
60
61
62
63
64
65
        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
c9fdeb00   Chunk   LSB and F4 added.
66

c9fdeb00   Chunk   LSB and F4 added.
67
            m = (hid_data[i] & 1)
c9fdeb00   Chunk   LSB and F4 added.
68
            if x > 0 and x & 1 != m:
6cbb3879   Chunk   F4 updated.
69
70
71
72
73
74
75
76
77
                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

8cfc1a23   Chunk   F5 half-finished.
78
79
80
81
    def _raw_extract(self, steg_data, num_bits):
        """
        Just a small helper function to extract hidden data.
        """
6cbb3879   Chunk   F4 updated.
82
        hid_data = np.zeros(num_bits, np.uint8)
6cbb3879   Chunk   F4 updated.
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
        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'"
c9fdeb00   Chunk   LSB and F4 added.

6cbb3879   Chunk   F4 updated.

c9fdeb00   Chunk   LSB and F4 added.

c9fdeb00   Chunk   LSB and F4 added.

6cbb3879   Chunk   F4 updated.

c9fdeb00   Chunk   LSB and F4 added.

8cfc1a23   Chunk   F5 half-finished.

6cbb3879   Chunk   F4 updated.

c9fdeb00   Chunk   LSB and F4 added.

6cbb3879   Chunk   F4 updated.

c9fdeb00   Chunk   LSB and F4 added.

8cfc1a23   Chunk   F5 half-finished.

c9fdeb00   Chunk   LSB and F4 added.

6cbb3879   Chunk   F4 updated.

c9fdeb00   Chunk   LSB and F4 added.

6cbb3879   Chunk   F4 updated.

c9fdeb00   Chunk   LSB and F4 added.

033d3b0d   Chunk   staged.