]> AND Private Git Repository - canny.git/blob - stc/exp/raphus/script_attaques.py
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
après remarques christophe
[canny.git] / stc / exp / raphus / script_attaques.py
1 #-*-coding:utf-8-*-
2
3 #############################################
4 # Script réalisé dans le cadre du papier
5 # concernant l'utilisation de plusieurs
6 # fonctions chaotiques (pas seulement la 
7 # négation vectorielle) pour le tatouage.
8 #
9 # On utilise 3 fonctions différentes, on tatoue
10 # dans le domaine ondelette.
11 #############################################
12
13 from numpy import * 
14 from sobel555_for_ensemble import *
15 from bbs import *
16
17 #from outilsBase import conversion, getBit, setBit
18 from random import *
19 from copy import deepcopy
20 import Image as im
21 from ImageChops import difference
22 from attaque import Attaque
23
24 def matrice_to_bits(matrice):
25     '''
26     Renvoie la matrice des écritures binaires de matrice.
27     Les coefficients floants deviennent des chaînes (str) de bits.
28     '''
29     (m,n) = matrice.shape
30     retour = []
31     for l in range(m):
32         ligne = []
33         for c in range(n):
34             ligne.append(conversion(str(matrice[l,c]),2))
35         retour.append(ligne)
36     return retour
37
38
39
40 def matrice_lscs(matrice,lscs):
41     '''
42     Matrice est une liste de listes, lscs est une liste.
43
44     A partir d'une matrice de coefficients binaires, vus comme
45     des chaines de caractères, extrait les bits dont les positions
46     sont données par la liste lscs.
47     
48     Dans la liste lscs, un entier positif signifie devant la virgule,
49     un entier négatif signifie derrière. Le premier bit devant la 
50     virgule est le bit 1, le premier bit derrière la virgule est le -1.
51
52     Le retour est une liste de bits (entiers).
53     '''
54     m,n = len(matrice), len(matrice[0])
55     retour = []
56     for l in range(m):
57         for c in range(n):
58             #num = str(round(float(matrice[l][c]),2))
59             num = matrice[l][c]
60
61             if '.' not in num:
62                 ent,dec = num.replace('-',''),'0'
63             else:
64                 ent,dec = num.replace('-','').split('.')
65             ent,dec = list(ent),list(dec)
66             ent.reverse()
67             for lsc in lscs:
68                 if lsc > 0 and len(ent)>=lsc:
69                     retour.append(ent[lsc-1])
70                 elif lsc<0 and len(dec)>=abs(lsc):
71                     retour.append(dec[abs(lsc)-1])
72                 else:
73                     retour.append('0')
74     return [int(k) for k in retour][:-3]
75
76
77 def embarque(liste,matrice,lscs):
78     m,n = len(matrice), len(matrice[0])
79     retour = []
80     cpt = 0
81     for l in range(m):
82         for c in range(n):
83             if '-' in matrice[l][c]:
84                 signe = '-'
85             else:
86                 signe = ''
87             if '.' not in matrice[l][c]:
88                 ent,dec = matrice[l][c].replace('-',''),'0'
89             else:
90                 ent,dec = matrice[l][c].replace('-','').split('.')
91             ent,dec = list(ent),list(dec)
92             ent.reverse()
93             maximum = max([abs(k) for k in lscs])
94             ent = list(''.join(ent).zfill(maximum+2))
95             dec = list(''.join(dec).zfill(maximum+2))
96             print dec
97             for lsc in lscs:
98                 if lsc > 0:
99                     ent[lsc-1] = str(liste[cpt])
100                 else:
101                     dec[abs(lsc)-1] = str(liste[cpt])
102                 cpt += 1
103             ent.reverse()
104             ent = ''.join(ent)
105             dec = ''.join(dec)
106             print ent+'.'+dec
107
108
109
110 def f(L):
111     assert len(L)%4 == 1
112     n = len(L)/4
113     retour = [int(not L[k]) for k in range(n)]
114     retour.extend([L[k-n] for k in range(n,2*n)])
115     retour.extend([int(L[k-2*n])*int(not L[k+1]) for k in range(2*n,4*n)])
116     retour.extend([int(not L[2*n])])
117     return retour
118
119
120
121
122 def f(L):
123     retour = [int(not L[0])]
124     retour.extend([L[k-1] for k in range(1,len(L))])
125     return retour    
126
127
128
129
130 def f(x):
131     rl=[]
132     k = 1
133     for el in x:
134         if k%2 != 0 :
135             rl.append(int(not el))
136         else:
137             rl.append(0 if sum(x[k-2:k])%2==0 else 1 )
138         k+=1
139     return rl
140
141
142
143
144 def f(i,x):
145     r = 0
146     if i%2 == 0 :
147         r = int(not x[i])
148     else:
149         r = 0 if sum(x[i-1:i+1])%2==0 else 1 
150     return r
151
152
153
154 def f(i,L):
155     return int(not L[i])
156
157
158
159 def embarque2(liste,matrice,lscs):
160     
161     m,n = len(matrice), len(matrice[0])
162     retour = deepcopy(matrice)
163     cpt = 0
164     for l in range(m):
165         for c in range(n):
166             for lsc in lscs:
167                 try:
168                     retour[l,c] = setBit(str(retour[l,c]),lsc, liste[cpt])
169                     cpt += 1
170                 except:
171                     pass
172     return retour
173
174 def PSNR(mat1,mat2):
175     (li,co) = mat1.shape
176     '''
177     Retourne le PSNR entre deux images.
178     '''
179     from math import log
180     densite = 2**8-1
181     eqm = 0
182     for k in range(li):
183         for l in range(co):
184             eqm+=(mat1[k][l] - mat2[k][l])**2
185     r= float(eqm)/li/co
186     if r !=0:
187         return 10*log(densite**2/r,10)
188     else:
189         return "Infini"
190
191
192     
193 def diff(mat1,mat2):
194     lm=len(mat1)
195     cpt = 0
196     for k in range(lm):
197         if mat1[k] != mat2[k] :
198             cpt +=1
199             #print mat1[k],mat2[k] 
200     return float(100)*cpt/lm
201
202 def arrondi_en_entier(mat):
203     (l,c) = mat.shape
204     return array([[round(mat[i][j]) for j in range(c)]for i in range(l)])
205         
206         
207
208
209 def sauve(data,outfile="dummy.png",file_msg="invader.png"):
210     (l,h)=im.open(file_msg).size
211     outIm = im.new('L',im.open(file_msg).size)
212     queue = [255 if x != 0 else 0 for x in data]
213     queue = queue[len(queue)-l*h:]
214     outIm.putdata(queue)
215     outIm.save("apresattaque.png")
216  
217
218             
219
220 def retrouve_message_parametre(file_msg="invader.png"):
221     
222     bbs = BlumBlumShub();
223     bbs.setN(M)
224     bbs.setSeed(X)
225
226     message = []
227     for c in [x if x==0 else 1 for x in im.open(file_msg).getdata()]:
228         message +=[c]
229     
230     leng_msg=len(message)
231     leng='%08d'%len(message)
232     len_leng=len(leng)
233     leng_error=int(len_leng)
234     leng_cor=leng    
235     List_pack=a2b_list(leng_cor)
236     List_pack += message
237     #print List_pack
238     leng_msg=len(List_pack)
239
240     List_random=[]
241     while len(List_random)<leng_msg:
242         List_random.extend(Denary2Binary(bbs.next()))
243
244
245     Message=[(int(List_pack[l])^int(List_random[l])) for l in xrange(len(List_pack))]
246     return (leng_msg,Message,List_random)
247
248                             
249
250
251
252 def experience(nom_fichier,leng_msg,Message,List_random):
253 #    print "message initial",Message
254     bit_to_read = 1
255     dd = im.open(nom_fichier)
256     dd = dd.convert('RGB') 
257     red, green, blue = dd.split()
258     level=red.copy()
259     at = level
260     (l,h)=red.size
261     marquee_matrice = np.array(at.getdata()).reshape((l,h))
262     level= array(level.getdata()).flatten()
263
264
265     ############# construire ici les attaques
266     nbexp=1
267     # matrices attaquees par rotation
268     attaquee_matrice = [] 
269     print "rotations"
270     for k in range(nbexp):
271         at  = Attaque.rotation(marquee_matrice,
272                                90,
273                                1)
274
275         m = [((abs(marquee_matrice-at)[i,j]),(i,j)) for i in xrange(l) for j in xrange(h)]
276       
277         #m =  sorted(m.items(), key=itemgetter(0))
278
279         print "diffence max", m
280         
281         attaquee_matrice += [at]
282
283     """
284
285     # matrices attaquees compression jpeg
286     print "compression"
287     for k in range(nbexp):
288         at  = Attaque.jpeg(marquee_matrice,
289                            nom_fichier,
290                            100-3*(k+1))
291         attaquee_matrice +=  [at]
292                                           
293     
294     # matrices attaquees compression jp2000
295     print "compression jp2000"
296     for k in range(nbexp):
297         at  = Attaque.jp2(marquee_matrice,
298                            nom_fichier,
299                            100-10*(k+1))
300         attaquee_matrice +=  [at]
301         
302
303
304     print "decoupage"        
305     # matrices attaquees decoupage
306     for k in range(nbexp):
307         t = int(0.1*(k+1)*min(taillex,tailley))
308         at  = Attaque.decoupage(marquee_matrice,
309                                 t,
310                                 (0,0))
311         attaquee_matrice +=  [at]
312
313     print "flou"            
314     # matrices attaquees flou
315     for k in range(nbexp):
316         t=0.6+0.08*(k+1)
317         at  = Attaque.flou(marquee_matrice,t)
318         attaquee_matrice +=  [at]
319         
320     print "contraste"            
321     # matrices attaquees contrast
322     for k in range(nbexp):
323         t=0.9#0.6+0.08*(k+1)
324         at  = Attaque.contraste(marquee_matrice,t)
325         attaquee_matrice +=  [at]
326
327     
328     # matrices attaquees redimensionnement
329     print "dimensionnement"
330     attaquee_matrice += [Attaque.redimensionnement(marquee_matrice,
331                                                    0.75,
332                                                    1)]
333     attaquee_matrice += [Attaque.redimensionnement(marquee_matrice,
334                                                    1.5,
335                                                    1)]
336     
337
338                                                    
339     """                                                   
340                                                    
341     print  "nombre d'attaques",len(attaquee_matrice)
342
343
344
345     c=0
346     for am in attaquee_matrice:
347         c +=1
348         attaquee = am        
349         im2 = im.new('L',dd.size)
350         im2.putdata(attaquee.flatten())
351         im2.save("apresRot.png")
352
353
354
355
356
357
358         #attaquee.copy()
359         print         im2,dd,leng_msg
360         [List_bit_to_change2,Weight2]=compute_filter_canny(im2,dd,leng_msg)
361         # on a mis dd et leng_msg : c'est juste pour la taille.
362         #level2= array(level.getdata()).flatten()
363
364         level2= array(im2.getdata()).flatten()
365
366         print "support2",len(List_bit_to_change2)
367         print "weight2",len(Weight2)
368
369         alpha = float(len(List_bit_to_change2))/len(Message)
370         assert alpha >= 2 
371         index = min(int(alpha),9)
372         H_hat2 = {
373         2 : [71,109],
374         3 : [95, 101, 121],
375         4 : [81, 95, 107, 121],
376         5 : [75, 95, 97, 105, 117],
377         6 : [73, 83, 95, 103, 109, 123],
378         7 : [69, 77, 93, 107, 111, 115, 121],
379         8 : [69, 79, 81, 89, 93, 99, 107, 119],
380         9 : [69, 79, 81, 89, 93, 99, 107, 119, 125]
381         }[index]
382
383
384
385         Stc_message2=[getBit(level2[l],bit_to_read) for l in List_bit_to_change2]
386         LL2=list(List_bit_to_change2)
387
388         print "Level",max([level2[l]-level[l] for l in xrange(len(Stc_message2))])
389         #print "List bit to change",max([LL2[l]-LL1[l] for l in xrange(len(Stc_message2))])
390         #print "Stc message", max([Stc_message[l]-Stc_message2[l] for l in xrange(len(Stc_message))])
391
392         Message2 = [x%2 for x in prod(H_hat2,len(Message),Stc_message2)] 
393
394         print "Message final",Message2
395         #print equiv(Message,Message2)
396
397         #print "fini"
398
399         l=0
400         val_mod2=0
401         list_msg=[]
402         decoded_msg=""
403         
404         MessageDecoded2=[(int(Message2[l])^int(List_random[l])) for l in xrange(len(Message2))]
405 #    print conv_list_bit(''.join([`MessageDecoded2[i]` for i in xrange(leng_error*8)]))
406 #    print int(conv_list_bit(''.join([`MessageDecoded2[i]` for i in xrange(leng_error*8)])))
407
408         #print "MessageDecoded2",MessageDecoded2
409         #print conv_list_bit(''.join([`MessageDecoded2[i]` for i in xrange(len(Message2))]))
410  
411
412     sauve(MessageDecoded2)
413
414     return MessageDecoded2
415
416
417
418
419
420
421 def main(): 
422     path_stego = '/home/couchot/rech/CCG12/canny/stc/exp/raphus/stego/'
423     path_cover = '/home/couchot/rech/BCG10/Oxford11/experiments/images/'
424     list_nb_bit=[]
425     l=0
426     listing = [957, 108, 106, 29, 431, 924, 262, 477, 346, 809]
427     listing = [809]
428     (leng_msg,Message,List_random) = retrouve_message_parametre()
429     print "params :", leng_msg,len(Message),List_random[0:5]
430     for infile in listing:
431         #    if l<10:
432         fi = path_cover+str(infile)+'.png'
433         fo = path_stego+str(infile)+'.png'
434         experience(fo,leng_msg,Message,List_random)
435         l+=1
436
437 if __name__ == "__main__":
438     main()
439
440
441
442
443
444