Blame view

msteg/steganography/LSB.py 3.15 KB
1d19f0e7   Chunk   staged.
1
2
3
4
__author__ = 'chunk'

import time
import numpy as np
ca73c96f   Chunk   Transformed into ...
5
6
7
from msteg import *
from common import *

1d19f0e7   Chunk   staged.
8
9
10
11
12
13
14

class LSB(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):
95f76ce8   Chunk   theis finished.论文...
15
        """
1d19f0e7   Chunk   staged.
16
17
18
        Constructor of the F3 class.
        """
        StegBase.__init__(self)
95f76ce8   Chunk   theis finished.论文...
19

1d19f0e7   Chunk   staged.
20
    def embed_raw_data(self, src_cover, src_hidden, tgt_stego):
95f76ce8   Chunk   theis finished.论文...
21
        """ This method embeds arbitrary data into a cover image.
1d19f0e7   Chunk   staged.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
        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)
95f76ce8   Chunk   theis finished.论文...
36

1d19f0e7   Chunk   staged.
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
    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):
        """
        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 x == 1 or cnt % 64 == 0: continue

            m = (hid_data[i] & 1)
            x[...] = (x & 0xfffffffe) | m  # '0xfffe' is enough, for elements are expected to be short integers.
95f76ce8   Chunk   theis finished.论文...
62
63
            i += 1
            if i == hid_data.size: break
1d19f0e7   Chunk   staged.
64
65
66

        return cov_data

95f76ce8   Chunk   theis finished.论文...
67
    def _raw_extract(self, steg_data, num_bits):
1d19f0e7   Chunk   staged.
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
        """
        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 x == 1 or cnt % 64 == 0: continue
            if j >= num_bits: break
            hid_data[j] = x & 1
            j = j + 1

        return hid_data

    def __str__(self):
        return 'LSB'


# this function might be a candidate for some kind of util module
def _parse_boolean(b):
    """Turns a boolean value into a string if it is not already a boolean.

    @param b: A boolean or a string.

    @return: A boolean value representing b. Every value of b is interpreted
             to be true except the boolean False and any string that satisfies
             a case-insensitive comparison with 'false'.
    """
    return b if isinstance(b, bool) else b.strip.lower() != 'false'