Commit 26e2fe9fe66de4396c58244e9e2e8cfb440e3292

Authored by Chunk
1 parent 8cfc1a23
Exists in master

MPB steganalysis algo half-finished,

jpegObj/__init__.py
... ... @@ -31,6 +31,7 @@ colorCode = {
31 31 }
32 32  
33 33 colorParam = ['Y', 'Cb', 'Cr']
  34 +colorMap = {'Y': 0, 'Cb': 1, 'Cr': 2}
34 35  
35 36 # The JPEG class
36 37 # ==============
... ... @@ -64,6 +65,7 @@ class Jpeg(Jsteg):
64 65 else:
65 66 self.key = None
66 67  
  68 +
67 69 def getkey(self):
68 70 """Return the key used to shuffle the coefficients."""
69 71 return self.key
... ... @@ -380,4 +382,27 @@ class Jpeg(Jsteg):
380 382 return S.astype(np.uint8)
381 383  
382 384  
  385 +def diffblock(c1, c2):
  386 + diff = False
  387 + if np.array_equal(c1, c2):
  388 + print("blocks match")
  389 + else:
  390 + print("blocks not match")
  391 + diff = True
  392 +
  393 + return diff
  394 +
  395 +
  396 +def diffblocks(a, b):
  397 + diff = False
  398 + cnt = 0
  399 + for comp in range(a.image_components):
  400 + xmax, ymax = a.Jgetcompdim(comp)
  401 + for y in range(ymax):
  402 + for x in range(xmax):
  403 + if a.Jgetblock(x, y, comp) != b.Jgetblock(x, y, comp):
  404 + print("blocks({},{}) in component {} not match".format(y, x, comp))
  405 + diff = True
  406 + cnt += 1
  407 + return diff, cnt
383 408  
... ...
jpegObj/__init__.pyc
No preview for this file type
msteg/steganalysis/ChiSquare.py
... ... @@ -23,12 +23,10 @@ import matplotlib.pyplot as plt
23 23 import itertools as it
24 24 from msteg.StegBase import StegBase
25 25  
26   -from stegotool.util.plugins import describe_and_annotate
27   -from stegotool.util.plugins import ImagePath, NewFilePath
28   -from stegotool.util.JPEGSteg import JPEGSteg
29   -from stegotool.util import rw_dct
  26 +from msteg.StegBase import *
30 27  
31   -class ChiSquare(JPEGSteg):
  28 +
  29 +class ChiSquare(StegBase):
32 30 """
33 31 The module contains only one method, <b>detect</b>.
34 32 """
... ...
msteg/steganalysis/MPB.py 0 → 100644
... ... @@ -0,0 +1,208 @@
  1 +__author__ = 'chunk'
  2 +"""
  3 +Yun Q. Shi, et al - A Markov Process Based Approach to Effective Attacking JPEG Steganography
  4 +"""
  5 +
  6 +import time
  7 +import math
  8 +import numpy as np
  9 +from msteg.StegBase import *
  10 +import mjsteg
  11 +import jpegObj
  12 +from common import *
  13 +
  14 +import csv
  15 +import json
  16 +import pickle
  17 +from sklearn import svm
  18 +
  19 +base_dir = '/home/hadoop/data/HeadShoulder/'
  20 +
  21 +class MPB(StegBase):
  22 + """
  23 + Markov Process Based Steganalyasis Algo.
  24 + """
  25 +
  26 + def __init__(self):
  27 + StegBase.__init__(self, sample_key)
  28 +
  29 + def get_trans_prob_mat_orig(self, ciq, T=4):
  30 + """
  31 + Original!
  32 + Calculate Transition Probability Matrix.
  33 +
  34 + :param ciq: jpeg DCT coeff matrix, 2-D numpy array of int16 (pre-abs)
  35 + :param T: signed integer, usually 1~7
  36 + :return: TPM - 3-D tensor, numpy array of size (2*T+1, 2*T+1, 4)
  37 + """
  38 + ciq = np.absolute(ciq).clip(0, T)
  39 + TPM = np.zeros((2 * T + 1, 2 * T + 1, 4), np.float64)
  40 + # Fh = np.diff(ciq, axis=-1)
  41 + # Fv = np.diff(ciq, axis=0)
  42 + Fh = ciq[:-1, :-1] - ciq[:-1, 1:]
  43 + Fv = ciq[:-1, :-1] - ciq[1:, :-1]
  44 + Fd = ciq[:-1, :-1] - ciq[1:, 1:]
  45 + Fm = ciq[:-1, 1:] - ciq[1:, :-1]
  46 +
  47 + Fh1 = Fh[:-1, :-1]
  48 + Fh2 = Fh[:-1, 1:]
  49 +
  50 + Fv1 = Fv[:-1, :-1]
  51 + Fv2 = Fv[1:, :-1]
  52 +
  53 + Fd1 = Fd[:-1, :-1]
  54 + Fd2 = Fd[1:, 1:]
  55 +
  56 + Fm1 = Fm[:-1, 1:]
  57 + Fm2 = Fm[1:, :-1]
  58 +
  59 + # original:(very slow!)
  60 + for n in range(-T, T + 1):
  61 + for m in range(-T, T + 1):
  62 + dh = np.sum(Fh1 == m) * 1.0
  63 + dv = np.sum(Fv1 == m) * 1.0
  64 + dd = np.sum(Fd1 == m) * 1.0
  65 + dm = np.sum(Fm1 == m) * 1.0
  66 +
  67 + if dh != 0:
  68 + TPM[m, n, 0] = np.sum(np.logical_and(Fh1 == m, Fh2 == n)) / dh
  69 +
  70 + if dv != 0:
  71 + TPM[m, n, 1] = np.sum(np.logical_and(Fv1 == m, Fv2 == n)) / dv
  72 +
  73 + if dd != 0:
  74 + TPM[m, n, 2] = np.sum(np.logical_and(Fd1 == m, Fd2 == n)) / dd
  75 +
  76 + if dm != 0:
  77 + TPM[m, n, 3] = np.sum(np.logical_and(Fm1 == m, Fm2 == n)) / dm
  78 +
  79 + # 1.422729s
  80 + return TPM
  81 +
  82 +
  83 + def get_trans_prob_mat(self, ciq, T=4):
  84 + """
  85 + Calculate Transition Probability Matrix.
  86 +
  87 + :param ciq: jpeg DCT coeff matrix, 2-D numpy array of int16 (pre-abs)
  88 + :param T: signed integer, usually 1~7
  89 + :return: TPM - 3-D tensor, numpy array of size (2*T+1, 2*T+1, 4)
  90 + """
  91 + # return self.get_trans_prob_mat_orig(ciq, T)
  92 + # timer = Timer()
  93 + ciq = np.absolute(ciq).clip(0, T)
  94 + TPM = np.zeros((2 * T + 1, 2 * T + 1, 4), np.float64)
  95 + # Fh = np.diff(ciq, axis=-1)
  96 + # Fv = np.diff(ciq, axis=0)
  97 + Fh = ciq[:-1, :-1] - ciq[:-1, 1:]
  98 + Fv = ciq[:-1, :-1] - ciq[1:, :-1]
  99 + Fd = ciq[:-1, :-1] - ciq[1:, 1:]
  100 + Fm = ciq[:-1, 1:] - ciq[1:, :-1]
  101 +
  102 + Fh1 = Fh[:-1, :-1]
  103 + Fh2 = Fh[:-1, 1:]
  104 +
  105 + Fv1 = Fv[:-1, :-1]
  106 + Fv2 = Fv[1:, :-1]
  107 +
  108 + Fd1 = Fd[:-1, :-1]
  109 + Fd2 = Fd[1:, 1:]
  110 +
  111 + Fm1 = Fm[:-1, 1:]
  112 + Fm2 = Fm[1:, :-1]
  113 +
  114 +
  115 +
  116 + # 0.089754s
  117 + # timer.mark()
  118 + # TPM[Fh1.ravel(), Fh2.ravel(), 0] += 1
  119 + # TPM[Fv1.ravel(), Fv2.ravel(), 1] += 1
  120 + # TPM[Fd1.ravel(), Fd2.ravel(), 2] += 1
  121 + # TPM[Fm1.ravel(), Fm2.ravel(), 3] += 1
  122 + # timer.report()
  123 +
  124 + # 1.936746s
  125 + # timer.mark()
  126 + for m, n in zip(Fh1.ravel(), Fh2.ravel()):
  127 + TPM[m, n, 0] += 1
  128 +
  129 + for m, n in zip(Fv1.ravel(), Fv2.ravel()):
  130 + TPM[m, n, 1] += 1
  131 +
  132 + for m, n in zip(Fd1.ravel(), Fd2.ravel()):
  133 + TPM[m, n, 2] += 1
  134 +
  135 + for m, n in zip(Fm1.ravel(), Fm2.ravel()):
  136 + TPM[m, n, 3] += 1
  137 + # timer.report()
  138 +
  139 + # 0.057505s
  140 + # timer.mark()
  141 + for m in range(-T, T + 1):
  142 + dh = np.sum(Fh1 == m) * 1.0
  143 + dv = np.sum(Fv1 == m) * 1.0
  144 + dd = np.sum(Fd1 == m) * 1.0
  145 + dm = np.sum(Fm1 == m) * 1.0
  146 +
  147 + if dh != 0:
  148 + TPM[m, :, 0] /= dh
  149 +
  150 + if dv != 0:
  151 + TPM[m, :, 1] /= dv
  152 +
  153 + if dd != 0:
  154 + TPM[m, :, 2] /= dd
  155 +
  156 + if dm != 0:
  157 + TPM[m, :, 3] /= dm
  158 + # timer.report()
  159 +
  160 + return TPM
  161 +
  162 + def _load_dataset(self,list_file):
  163 + """
  164 + load jpeg dataset according to a file of file-list.
  165 +
  166 + :param list_file: a tsv file with each line for a jpeg file path
  167 + :return:(X,Y) for SVM
  168 + """
  169 + X = []
  170 + Y = []
  171 + dict_tagbuf = {}
  172 + dict_dataset = {}
  173 +
  174 + with open(list_file, 'rb') as tsvfile:
  175 + tsvfile = csv.reader(tsvfile, delimiter='\t')
  176 + for line in tsvfile:
  177 + imgname = line[0] + '.jpg'
  178 + dict_tagbuf[imgname] = line[1]
  179 +
  180 + dir = base_dir + 'Feat/'
  181 + for path, subdirs, files in os.walk(dir + 'Train/'):
  182 + for name in files:
  183 + featpath = os.path.join(path, name)
  184 + # print featpath
  185 + with open(featpath, 'rb') as featfile:
  186 + imgname = path.split('/')[-1] + name.replace('.mpb', '.jpg')
  187 + dict_dataset[imgname] = json.loads(featfile.read())
  188 +
  189 + for imgname, tag in dict_tagbuf.items():
  190 + tag = 1 if tag == 'True' else 0
  191 + X.append(dict_dataset[imgname])
  192 + Y.append(tag)
  193 +
  194 + return X, Y
  195 +
  196 +
  197 +
  198 +
  199 +
  200 +
  201 +
  202 +
  203 +
  204 +
  205 +
  206 +
  207 +
  208 +
... ...
msteg/steganalysis/MPB.pyc 0 → 100644
No preview for this file type
msteg/steganography/F5.py
1 1 __author__ = 'chunk'
2 2  
3 3 """
  4 +ref - http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.115.3651&rep=rep1&type=pdf
  5 +
4 6 <p>This module implements the rather sophisticated F5 algorithm which was
5 7 invented by Andreas Westfeld.</p>
6 8  
... ...
msteg/steganography/F5.pyc
No preview for this file type
test_jpeg.py
... ... @@ -4,6 +4,7 @@ import numpy as np
4 4 import mjsteg
5 5 import jpegObj
6 6 from jpegObj import base
  7 +
7 8 from common import *
8 9  
9 10 timer = Timer()
... ... @@ -21,30 +22,8 @@ sample_key = [46812L, 20559L, 31360L, 16681L, 27536L, 39553L, 5427L, 63029L, 565
21 22 5908L, 59816L, 56765L]
22 23  
23 24  
24   -def diffblock(c1, c2):
25   - diff = False
26   - if np.array_equal(c1, c2):
27   - print("blocks match")
28   - else:
29   - print("blocks not match")
30   - diff = True
31   -
32   - return diff
33 25  
34 26  
35   -def diffblocks(a, b):
36   - diff = False
37   - cnt = 0
38   - for comp in range(a.image_components):
39   - xmax, ymax = a.Jgetcompdim(comp)
40   - for y in range(ymax):
41   - for x in range(xmax):
42   - if a.Jgetblock(x, y, comp) != b.Jgetblock(x, y, comp):
43   - print("blocks({},{}) in component {} not match".format(y, x, comp))
44   - diff = True
45   - cnt += 1
46   - return diff, cnt
47   -
48 27  
49 28 def test_setblocks():
50 29 """
... ... @@ -63,7 +42,7 @@ def test_setblocks():
63 42  
64 43 ima = jpegObj.Jpeg("res/test3.jpg")
65 44 imb = jpegObj.Jpeg("res/test4.jpg")
66   - diffblocks(ima, imb)
  45 + jpegObj.diffblocks(ima, imb)
67 46  
68 47  
69 48 def test_setblocks2():
... ... @@ -88,7 +67,7 @@ def test_setblocks2():
88 67  
89 68 ima = jpegObj.Jpeg("res/test3.jpg")
90 69 imb = jpegObj.Jpeg("res/test4.jpg")
91   - diffblocks(ima, imb)
  70 + jpegObj.diffblocks(ima, imb)
92 71  
93 72  
94 73 def test_setblock():
... ... @@ -106,7 +85,7 @@ def test_setblock():
106 85 blocks2 = imb.Jgetblock(1, 0, 0)
107 86 block_to_show = np.frombuffer(blocks2, dtype=np.int16, count=-1, offset=0).reshape(8, 8)
108 87 print block_to_show
109   - diffblock(blocks1, block_to_show)
  88 + jpegObj.diffblock(blocks1, block_to_show)
110 89  
111 90  
112 91 def test_split():
... ... @@ -197,7 +176,7 @@ if __name__ == &#39;__main__&#39;:
197 176 imc = jpegObj.Jpeg("res/steged.jpg", key=sample_key)
198 177 print ima.Jgetcompdim(0)
199 178 print ima.getkey(), imc.getkey()
200   - print diffblocks(ima, imc)
  179 + print jpegObj.diffblocks(ima, imc)
201 180  
202 181 # c1 = ima.getCoefBlocks()
203 182 # c2 = imb.getCoefBlocks()
... ...
test_steganal.py 0 → 100644
... ... @@ -0,0 +1,49 @@
  1 +__author__ = 'chunk'
  2 +
  3 +import numpy as np
  4 +import pylab as P
  5 +import pylab as plt
  6 +
  7 +import mjpeg
  8 +import mjsteg
  9 +import jpegObj
  10 +from msteg.steganography import LSB, F3, F4, F5
  11 +from msteg.steganalysis import MPB
  12 +
  13 +from common import *
  14 +
  15 +
  16 +timer = Timer()
  17 +
  18 +sample = [[7, 12, 14, -12, 1, 0, -1, 0],
  19 + [6, 5, -10, 0, 6, 0, 0, 0],
  20 + [0, 6, -5, 4, 0, -1, 0, 0],
  21 + [0, -3, 0, 1, -1, 0, 0, 0],
  22 + [-3, 5, 0, 0, 0, 0, 0, 0],
  23 + [2, -1, 0, 0, 0, 0, 0, 0],
  24 + [0, 0, 0, 0, 0, 0, 0, 0],
  25 + [0, 0, 0, 0, 0, 0, 0, 0]]
  26 +
  27 +sample_key = [46812L, 20559L, 31360L, 16681L, 27536L, 39553L, 5427L, 63029L, 56572L, 36476L, 25695L, 61908L, 63014L,
  28 + 5908L, 59816L, 56765L]
  29 +
  30 +txtsample = [116, 104, 105, 115, 32, 105, 115, 32, 116, 111, 32, 98, 101, 32, 101, 109, 98, 101, 100, 101, 100, 46, 10]
  31 +
  32 +if __name__ == '__main__':
  33 + timer = Timer()
  34 +
  35 + timer.mark()
  36 + ima = jpegObj.Jpeg("res/test3.jpg", key=sample_key)
  37 + timer.report() # 0.006490s
  38 +
  39 + ciq = ima.coef_arrays[jpegObj.colorMap['Y']]
  40 + timer.report() # 0.000019s
  41 +
  42 + mpbSteg = MPB.MPB()
  43 + tpm = mpbSteg.get_trans_prob_mat(ciq)
  44 + timer.report() # 1.365718s
  45 +
  46 + print tpm, tpm.shape
  47 + pass
  48 +
  49 +
... ...