Suite aux différents post sur la stéganographie, je me suis amusé a faire une petite interface qui permet de mettre / lire du texte contenu dans une image.
J'ai ajouté une option de cryptage XOR via un mot de passe, avant d'envoyé le texte dans l'image. (histoire de corsé la chose)
les procédures qui envoient / récupères / cryptes le texte, sont tous de Dobro
L'interface est en 2 onglets. 1 pour le cryptage et l'autre pour le décryptage.
Voici le code:
Code : Tout sélectionner
; ///////////////////////////////////////////////
; // Autor : Venom //
; // Project name : Texte In Image //
; // Version : V 1.0 //
; // Compilator : PureBasic V5.71 //
; // Date : 03/07/2019 //
; // OS : Windows 10 //
; ///////////////////////////////////////////////
;- Window Constants
Enumeration
#Window_0
EndEnumeration
;- gadgets Constants
Enumeration
#Panel_0
; onglet 1
#Frame_Load_image_Cryptage
#Button_Load_image_Cryptage
#String_Load_image_Cryptage
#Frame_Load_Texte_Cryptage
#String_Load_Texte_Cryptage
#Frame_Mots_De_Passe_Cryptage
#String_Mots_De_Passe_Cryptage
#String_Verf_Mots_De_Passe_Cryptage
#Frame_Lancer_Cryptage
#Button_Lancer_Cryptage
#Image_Cryptage
; onglet 2
#Frame_Load_image_Decodage
#Button_Load_image_Decodage
#String_Load_image_Decodage
#Frame_Load_Texte_Decodage
#String_Load_Texte_Decodage
#Frame_Mots_De_Passe_Decodage
#String_Mots_De_Passe_Decodage
#String_Verf_Mots_De_Passe_Decodage
#Frame_Lancer_Decodage
#Button_Lancer_Decodage
#Image_Decodage
EndEnumeration
UsePNGImageEncoder()
UsePNGImageDecoder()
Declare encode_steganosorus2(ID,name_image$,message$)
Declare.s decode_steganosorus2(ID, name_image$)
Declare.s Encodage_Decodage_XOR(chaine$,Pass$,Mode)
Global Chemin_De_Image$
Global Texte_A_Encoder$
Global Mots_De_Passe_Final$
If OpenWindow(#Window_0, 0, 0, 400, 405, "Stega Texte In Image", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered)
PanelGadget(#Panel_0, 0, 0, 400, 405)
;{ onglet 1
AddGadgetItem (#Panel_0, 1, "Inseret un texte dans une image ")
FrameGadget(#Frame_Load_image_Cryptage, 10, 10, 380, 50, "Image qui dissimulera le texte", 0)
ButtonGadget(#Button_Load_image_Cryptage, 20, 30, 100, 20, "Choisir une image", 0)
StringGadget(#String_Load_image_Cryptage, 130, 30, 250, 20, "", #PB_String_ReadOnly)
FrameGadget(#Frame_Load_Texte_Cryptage, 10, 70, 380, 150, "Texte qui sera dissimuler dans l'image", 0)
EditorGadget(#String_Load_Texte_Cryptage, 20, 90, 360, 120, #PB_Editor_WordWrap)
FrameGadget(#Frame_Mots_De_Passe_Cryptage, 10, 230, 380, 80, "Mots de passe pour crypter le texte", 0)
StringGadget(#String_Mots_De_Passe_Cryptage, 20, 250, 360, 20, "", #PB_String_Password)
StringGadget(#String_Verf_Mots_De_Passe_Cryptage, 20, 280, 360, 20, "", #PB_String_Password)
FrameGadget(#Frame_Lancer_Cryptage, 10, 320, 380, 50, "Lancer le cryptage", 0)
ButtonGadget(#Button_Lancer_Cryptage, 20, 340, 360, 20, "Lancer le cryptage", 0)
;}
;{ onglet 2
AddGadgetItem (#Panel_0, 2, "Récuperer le texte d'une image ")
FrameGadget(#Frame_Load_image_Decodage, 10, 10, 380, 50, "Image qui contient le texte", 0)
ButtonGadget(#Button_Load_image_Decodage, 20, 30, 100, 20, "Choisir une image", 0)
StringGadget(#String_Load_image_Decodage, 130, 30, 250, 20, "", #PB_String_ReadOnly)
FrameGadget(#Frame_Mots_De_Passe_Decodage, 10, 70, 380, 80, "Mots de passe pour décrypter le texte", 0)
StringGadget(#String_Mots_De_Passe_Decodage, 20, 90, 360, 20, "", #PB_String_Password)
StringGadget(#String_Verf_Mots_De_Passe_Decodage, 20, 120, 360, 20, "", #PB_String_Password)
FrameGadget(#Frame_Lancer_Decodage, 10, 160, 380, 50, "Lancer le décryptage", 0)
ButtonGadget(#Button_Lancer_Decodage, 20, 180, 360, 20, "Lancer le décryptage", 0)
FrameGadget(#Frame_Load_Texte_Decodage, 10, 220, 380, 150, "Texte qui est dans l'image", 0)
EditorGadget(#String_Load_Texte_Decodage, 20, 240, 360, 120, #PB_String_ReadOnly | #PB_Editor_WordWrap)
;}
EndIf
Repeat
EventID = WaitWindowEvent()
If EventID = #PB_Event_Gadget
Select EventGadget()
;{ onglet 1
Case #Button_Load_image_Cryptage
name_image$ = OpenFileRequester("Choisir une image", "", "Image Compatible|*.png;*.bmp", 0)
If name_image$ <>""
SetGadgetText(#String_Load_image_Cryptage,name_image$)
LoadImage(#image_Cryptage,name_image$)
EndIf
Case #Button_Lancer_Cryptage
; vérification qu'il y a bien une image de séléctionner
Resultat_Image = Len(GetGadgetText(#String_Load_image_Cryptage))
If Resultat_Image = 0
MessageRequester("Information", "Une image doit être choisi pour lancer le cryptage.", #PB_MessageRequester_Error)
Resultat_Image = 0
Else
Resultat_Image = 1
EndIf
; vérification qu'il y a bien un texte a crypter
Resultat_Load_Texte.s = GetGadgetText(#String_Load_Texte_Cryptage)
If Resultat_Load_Texte.s = ""
MessageRequester("Information", "Un texte doit être entrée pour le dissimuler dans l'image.", #PB_MessageRequester_Error)
Resultat_Load_T = 0
Else
Texte_A_Encoder$ = GetGadgetText(#String_Load_Texte_Cryptage)
Resultat_Load_T = 1
EndIf
; verification qu'un mot de passe est entrée et que les 2 mots de passes sont identiques
Resultat_Mots_De_Passe = Len(GetGadgetText(#String_Mots_De_Passe_Cryptage))
Resultat_Verif_Mots_De_Passe = Len(GetGadgetText(#String_Verf_Mots_De_Passe_Cryptage))
If Resultat_Mots_De_Passe = 0 Or Resultat_Verif_Mots_De_Passe = 0
MessageRequester("Information", "Le mots de passe doit être entrée dans les 2 chants.", #PB_MessageRequester_Error)
Resultat_Mots_De_Passe = 0
ElseIf GetGadgetText(#String_Mots_De_Passe_Cryptage) = GetGadgetText(#String_Verf_Mots_De_Passe_Cryptage)
Mots_De_Passe_Final$ = GetGadgetText(#String_Mots_De_Passe_Cryptage)
Resultat_Mots_De_Passe = 1
Else
MessageRequester("Information", "Les mots de passes ne sont pas identiques.", #PB_MessageRequester_Error)
Resultat_Mots_De_Passe = 0
EndIf
; lancement du cryptage
If Resultat_Image And Resultat_Load_T And Resultat_Mots_De_Passe = 1
Texte_Crypter$ = Encodage_Decodage_XOR(Texte_A_Encoder$, Mots_De_Passe_Final$, #True)
encode_steganosorus2(#image_Cryptage, name_image$, Texte_Crypter$)
EndIf
;}
;{ onglet 2
Case #Button_Load_image_Decodage
name_image$ = OpenFileRequester("Choisir une image", "", "Image Compatible|*.png;*.bmp", 0)
If name_image$ <>""
SetGadgetText(#String_Load_image_Decodage,name_image$)
LoadImage(#Image_Decodage,name_image$)
EndIf
Case #Button_Lancer_Decodage
; vérification qu'il y a bien une image de séléctionner
Resultat_Image = Len(GetGadgetText(#String_Load_image_Decodage))
If Resultat_Image = 0
MessageRequester("Information", "Une image doit être choisi pour lancer le décryptage.", #PB_MessageRequester_Error)
Resultat_Image = 0
Else
Resultat_Image = 1
EndIf
; verification qu'un mot de passe est entrée et que les 2 mots de passes sont identiques
Resultat_Mots_De_Passe = Len(GetGadgetText(#String_Mots_De_Passe_Decodage))
Resultat_Verif_Mots_De_Passe = Len(GetGadgetText(#String_Verf_Mots_De_Passe_Decodage))
If Resultat_Mots_De_Passe = 0 Or Resultat_Verif_Mots_De_Passe = 0
MessageRequester("Information", "Le mots de passe doit être entrée dans les 2 chants.", #PB_MessageRequester_Error)
Resultat_Mots_De_Passe = 0
ElseIf GetGadgetText(#String_Mots_De_Passe_Decodage) = GetGadgetText(#String_Verf_Mots_De_Passe_Decodage)
Mots_De_Passe_Final$ = GetGadgetText(#String_Mots_De_Passe_Decodage)
Resultat_Mots_De_Passe = 1
Else
MessageRequester("Information", "Les mots de passes ne sont pas identiques.", #PB_MessageRequester_Error)
Resultat_Mots_De_Passe = 0
EndIf
; lancement du décryptage
If Resultat_Image And Resultat_Mots_De_Passe = 1
decode_steganosorus2(ID, name_image$)
MessageRequester("Information","le texte a bien était décrypter.", #PB_MessageRequester_Info)
EndIf
;}
EndSelect
EndIf
Until EventID = #PB_Event_CloseWindow
Procedure encode_steganosorus2(ID,name_image$, message$)
; By Dobro
; encodeur
largeur=ImageWidth(ID)
hauteur=ImageHeight(ID)
StartDrawing(ImageOutput(ID))
compteur_pos=1
; on encodera la longueur du text dans le dernier point de l'image
longueur=Len(message$)+1
For y=0 To hauteur-1
For x=0 To largeur-9 Step 8
octet_rouge$="":octet_vert$="":octet_bleu$=""
lettre.s=Mid(message$,compteur_pos,1)
lettre2.s=Mid(message$,compteur_pos+1,1)
lettre3.s=Mid(message$,compteur_pos+2,1)
Letter_rouge=Asc(lettre.s) :Letter_vert=Asc(lettre2.s):Letter_bleu=Asc(lettre3.s)
octet_lettre.s=Bin(letter_rouge,#PB_Ascii)
octet_lettre.s=RSet(octet_lettre.s,8,"0")
octet_lettre2.s=Bin(letter_vert,#PB_Ascii)
octet_lettre2.s=RSet(octet_lettre2.s,8,"0")
octet_lettre3.s=Bin(letter_bleu,#PB_Ascii)
octet_lettre3.s=RSet(octet_lettre3.s,8,"0")
If compteur_pos<longueur
For i=0 To 7 ; paquet de 8 bits pour encoder 1 lettre
coul=Point(x+i,y)
rouge=Red(coul)
vert=Green(coul)
bleu=Blue(coul)
octet_rouge$=Bin(rouge,#PB_Ascii )
octet_rouge$=RSet(octet_rouge$,8,"0")
;
octet_vert$=Bin(vert,#PB_Ascii )
octet_vert$=RSet(octet_vert$,8,"0")
;
octet_bleu$=Bin(bleu,#PB_Ascii )
octet_bleu$=RSet(octet_bleu$,8,"0")
;
bit$=Mid(octet_lettre.s,i+1,1); prend l'extrait du bit de la lettre
bit2$=Mid(octet_lettre2.s,i+1,1); prend l'extrait du bit de la lettre
bit3$=Mid(octet_lettre3.s,i+1,1); prend l'extrait du bit de la lettre
;
If bit$<>""
octet_rouge_ap$=Left(octet_rouge$,Len(octet_rouge$)-1)+bit$ ; le colle a la fin de l'octet rouge en cours
EndIf
If bit2$<>""
octet_vert_ap$=Left(octet_vert$,Len(octet_vert$)-1)+bit2$ ; le colle a la fin de l'octet rouge en cours
EndIf
If bit3$<>""
octet_bleu_ap$=Left(octet_bleu$,Len(octet_bleu$)-1)+bit3$ ; le colle a la fin de l'octet rouge en cours
EndIf
Plot(x+i,y,RGB(Val("%"+octet_rouge_ap$),Val("%"+octet_vert_ap$),Val("%"+octet_bleu_ap$)))
Next i
compteur_pos=compteur_pos+3
Else ; si on est la, c'est que le message est fini et qu'il reste des pixel a dessiner
coul=Point(x,y)
rouge=Red(coul)
vert=Green(coul)
bleu=Blue(coul)
Plot(x,y,RGB(rouge,vert,bleu))
EndIf
Next x
Next y
Plot(largeur-1,hauteur-1,longueur) ; on pose la longueur du message dans le dernier point de l'image
MessageRequester("Information","le texte a bien était caché dans l'image.", #PB_MessageRequester_Info )
StopDrawing()
Extention$ = GetExtensionPart(name_image$)
Chemin_De_Image_Sans_Extention$ = Left(name_image$, Len(name_image$)-4)
SaveImage(ID, Chemin_De_Image_Sans_Extention$+" MOD."+Extention$)
EndProcedure
Procedure.s decode_steganosorus2(ID, name_image$)
LoadImage(ID,name_image$)
largeur=ImageWidth(ID)
hauteur=ImageHeight(ID)
StartDrawing(ImageOutput(ID))
; By Dobro
;decodeur
longueur= Point(largeur-1,hauteur-1)-1 ; la longueur du message se trouve dans le dernier point de l'image
For y=0 To hauteur-1
For x=0 To largeur-9 Step 8
octetrouge$="" :octetvert$="":octetbleu$=""
For i=0 To 7
coul=Point(x+i,y)
rouge=Red(coul)
vert=Green(coul)
bleu=Blue(coul)
;premiere lettre
bit$=Bin(rouge,#PB_Ascii )
bit$=RSet(bit$,8,"0") ; alignement
octetrouge$=octetrouge$+Right(bit$,1)
;deuxieme lettre
bit2$=Bin(vert,#PB_Ascii )
bit2$=RSet(bit2$,8,"0") ; alignement
octetvert$=octetvert$+Right(bit2$,1)
;troisieme lettre
bit3$=Bin(bleu,#PB_Ascii )
bit3$=RSet(bit3$,8,"0") ; alignement
octetbleu$=octetbleu$+Right(bit3$,1)
Next i
car=Val("%"+octetrouge$)
car2=Val("%"+octetvert$)
car3=Val("%"+octetbleu$)
l$=l$+Chr(car)+Chr(car2)+Chr(car3) ; pose 3 lettres d'un coup
Next x
Next y
;- on recupere le texte crypter et on le decrypte
Texte_Decrypter$ = Encodage_Decodage_XOR(Left(L$,longueur), Mots_De_Passe_Final$, #False)
SetGadgetText(#String_Load_Texte_Decodage, Texte_Decrypter$)
StopDrawing()
EndProcedure
Procedure.s Encodage_Decodage_XOR(chaine$,Pass$,Mode)
; By Zorro
; ENCODAGE XOR
For i=1 To Len(chaine$)
pos=pos+1
If pos>Len(pass$):Pos=1:EndIf
cclair=Asc(Mid(chaine$,i,1))
cpass=Asc(Mid(pass$,pos,1))
Select Mode
Case #True ; encodage XOR
cencode=cclair!(cpass)
If cencode=0 ; Cas ou le pass et le clair soit pareil , ou le le code soit plus petit que "l'espace"
cencode=255 ; recodage si pareil en fait on creer un Flag "255" signifiera qu'on utilisera le meme caractere que le pass donc on encode pas vraiment
EndIf
encode$=encode$+Chr(cencode)
Case #False ; decodage XOR
If cclair=255 ; si le code analysé et encodé est 255 alors cela signifie que
cdecod= cpass ;le caractere est le meme que le pass ....
Else
cdecod=cclair!(cpass)
EndIf
decode$=decode$+Chr(cdecod)
EndSelect
Next i
If Mode=#True
ProcedureReturn encode$
Else
ProcedureReturn decode$
EndIf
EndProcedure
@++