├── grace_hopper.png ├── Encoded_Image.png ├── README.md └── steganography.py /grace_hopper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shlok-crypto/Steganography-Software/HEAD/grace_hopper.png -------------------------------------------------------------------------------- /Encoded_Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Shlok-crypto/Steganography-Software/HEAD/Encoded_Image.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Steganography-Software 2 | 3 | Art of Encrypting and Hiding data within images. I build an image **Steganography Software** from scratch using Python. 4 | 5 | I utilized skills of: 6 | * Encryption, 7 | * Binary Conversion 8 | * File Handling 9 | * Data Segregation 10 | * Data Manipulation 11 | 12 | # **Project Scope:** 13 | This project is developed for hiding information in any image file. The scope of the project is the implementation of steganography tools for hiding information includes any type of information file and image files and the path where the user wants to save Image and extruded file. 14 | 15 | # **Methodology:** 16 | The user needs to run the application. The user has two tab options – encrypt and decrypt. If the user select encrypt, the application gives the screen to select an image file, information file, and option to save the image file. If the user select decrypt, the application gives the screen to select the image file and ask the path where the user wants to save the secrete file. 17 | This project has two methods – Encrypt and Decrypt. 18 | In encryption, the secrete information is hiding in any type of image file. 19 | Decryption is getting the secrete information from an image file. 20 | Graphical Representation 21 | 22 | ***The graphical representation of the Steganography system is as follows:*** 23 | 24 | ![image](https://user-images.githubusercontent.com/83566027/116849121-af43b580-ac0b-11eb-89a0-297039dbde9e.png) 25 | 26 | # **Encoding** 27 | 28 | There are a lot of algorithms that can be used to encode data into the image, and in fact, you can also make one yourself. The one being used in this blog is easy to understand and implement, as well. 29 | 30 | *The algorithm is as follows:* 31 | 32 | 1) For each character in the data, its ASCII value is taken and converted into an 8-bit binary [1]. 33 | 2) Three pixels are read at a time having a total of 3*3=9 RGB values. 34 | The first eight RGB values are used to store one character that is converted into an 8-bit binary. 35 | 3) The corresponding RGB value and binary data are compared. If the binary digit is 1 then the RGB value is converted to odd and, otherwise, even. 36 | 4) The ninth value determines if more pixels should be read or not. 37 | If there is more data to be read, i.e. encoded or decoded, then the ninth-pixel changes to even. Otherwise, if we want to stop reading pixels further, then make it odd. 38 | 5) Repeat this process until all the data is encoded into the image. 39 | 40 | ![image](https://user-images.githubusercontent.com/83566027/116850104-a48a2000-ac0d-11eb-9161-029a77e9012c.png) 41 | 42 | 43 | # **Decoding** 44 | 45 | For decoding, we shall try to *reverse* the previous algorithm that we used to encode data. 46 | 47 | *The algorithm is as follows:* 48 | 1) Again, three pixels are read at a time. The first 8 RGB values give us information about the secret data, and the ninth value tells us whether to move forward or not. 49 | 2) For the first eight values, if the value is odd, then the binary bit is 1, otherwise it is 0. 50 | 3) The bits are concatenated to a string, and with every three pixels, we get a byte of secret data, which means one character. 51 | 4) Now, if the ninth value is even then we keep reading pixels three at a 52 | 53 | # ***My Implementation of Steganography Software is as follows:*** 54 | ![image](https://user-images.githubusercontent.com/83566027/116848907-452b1080-ac0b-11eb-998b-2fbc763c4d96.png) 55 | 56 | # **Conclusion** 57 | 58 | The *new image(Encoded_Image.png)* looks **exacatly the same** as the *orignal image(GraceHoper.png)* to the human eyes. 59 | The slight change in the pixel values is unnoticeable to the human eyes. It is **impossible** for a human to *distinguish between the two images.* 60 | Even for a computer, it will be *very difficult* to detect the image as a Steganography image if it *does not have access to the original image*, to compare the two against each other. 61 | 62 | End 63 | -------------------------------------------------------------------------------- /steganography.py: -------------------------------------------------------------------------------- 1 | from PIL import Image 2 | 3 | # Convert encoding data into 8-bit binary 4 | # form using ASCII value of characters 5 | def genData(data): 6 | 7 | # list of binary codes 8 | # of given data 9 | newd = [] 10 | 11 | for i in data: 12 | newd.append(format(ord(i), '08b')) 13 | return newd 14 | 15 | # Pixels are modified according to the 16 | # 8-bit binary data and finally returned 17 | def modPix(pix, data): 18 | 19 | datalist = genData(data) 20 | lendata = len(datalist) 21 | imdata = iter(pix) 22 | 23 | for i in range(lendata): 24 | 25 | # Extracting 3 pixels at a time 26 | pix = [ value for value in imdata.__next__()[:3] + imdata.__next__()[:3] + imdata.__next__()[:3] ] 27 | 28 | # Pixel value should be made 29 | # odd for 1 and even for 0 30 | for j in range(0, 8): 31 | if (datalist[i][j] == '0' and pix[j]% 2 != 0): 32 | pix[j] -= 1 33 | 34 | elif (datalist[i][j] == '1' and pix[j] % 2 == 0): 35 | if(pix[j] != 0): 36 | pix[j] -= 1 37 | else: 38 | pix[j] += 1 39 | # pix[j] -= 1 40 | 41 | # Eighth pixel of every set tells 42 | # whether to stop ot read further. 43 | # 0 means keep reading; 1 means stop 44 | # message is over. 45 | if (i == lendata - 1): 46 | if (pix[-1] % 2 == 0): 47 | if(pix[-1] != 0): 48 | pix[-1] -= 1 49 | else: 50 | pix[-1] += 1 51 | 52 | else: 53 | if (pix[-1] % 2 != 0): 54 | pix[-1] -= 1 55 | 56 | pix = tuple(pix) 57 | yield pix[0:3] 58 | yield pix[3:6] 59 | yield pix[6:9] 60 | 61 | def encode_enc(newimg, data): 62 | w = newimg.size[0] 63 | (x, y) = (0, 0) 64 | for pixel in modPix(newimg.getdata(), data): 65 | 66 | # Putting modified pixels in the new image 67 | newimg.putpixel((x, y), pixel) 68 | if (x == w - 1): 69 | x = 0 70 | y += 1 71 | else: 72 | x += 1 73 | 74 | # Encode data into image 75 | def encode(): 76 | img = input("Enter image name(with extension) : ") 77 | image = Image.open(img, 'r') 78 | image.show() 79 | 80 | data = input("Enter data to be encoded : ") 81 | if (len(data) == 0): 82 | raise ValueError('Data is empty') 83 | 84 | newimg = image.copy() 85 | encode_enc(newimg, data) 86 | 87 | new_img_name = input("Enter the name of new image(with extension) : ") 88 | newimg.save(new_img_name, str(new_img_name.split(".")[1].upper())) 89 | 90 | 91 | 92 | 93 | # Decode the data in the image 94 | def decode(): 95 | img = input("Enter image name(with extension) : ") 96 | image = Image.open(img, 'r') 97 | 98 | data = '' 99 | imgdata = iter(image.getdata()) 100 | 101 | while (True): 102 | pixels = [value for value in imgdata.__next__()[:3] + 103 | imgdata.__next__()[:3] + 104 | imgdata.__next__()[:3]] 105 | 106 | # string of binary data 107 | binstr = '' 108 | 109 | for i in pixels[:8]: 110 | if (i % 2 == 0): 111 | binstr += '0' 112 | else: 113 | binstr += '1' 114 | 115 | data += chr(int(binstr, 2)) 116 | if (pixels[-1] % 2 != 0): 117 | return data 118 | 119 | # Main Function 120 | def incript(): 121 | a = int(input(":: Welcome to Steganography ::\n" 122 | "1. Encode\n2. Decode\n")) 123 | if (a == 1): 124 | encode() 125 | 126 | elif (a == 2): 127 | print("Decoded Word : " + decode()) 128 | else: 129 | raise Exception("Enter correct input") 130 | 131 | 132 | 133 | 134 | #### MY TRY 135 | 136 | 137 | 138 | # # Online Python compiler (interpreter) to run Python online. 139 | # # Write Python 3 code in this online editor and run it. 140 | # rgb_value = [(27, 64, 164), (248, 244, 194), (174, 246, 250), 141 | # (149, 95, 232), (188, 156, 169), (71, 167, 127), 142 | # (132, 173, 97), (113, 69, 206), (255, 29, 213), 143 | # (53, 153, 220), (246, 225, 229), (142, 82, 175)] 144 | # cols, rows = 3, 12 145 | # rgb = [[0 for i in range(cols)] for j in range(rows)] 146 | # 147 | # for p in range(0, 12): 148 | # for j in range(0, 3): 149 | # rgb[p][j] = rgb_value[p][j] 150 | # 151 | # print(rgb) 152 | # print("\nogg\n") 153 | # 154 | # bi = format(ord("H"), '08b') 155 | # print(bi) 156 | # 157 | # # bi => 01001000 158 | # # if 0 then even ie: 2,4 159 | # # if 1 then odd ie: 3,5 160 | # i = 0 161 | # 162 | # for p in range(0, 9): 163 | # for j in range(0, 3): 164 | # if i <8: 165 | # # making even value odd = 3 => 2 166 | # if (bi[i] == '0' and rgb[p][j] % 2 != 0): 167 | # rgb[p][j] -= 1 168 | # print("1i=>",i,bi[i]) 169 | # i += 1 170 | # # making odd value even = 2 => 1 171 | # elif (bi[i] == '1' and rgb[p][j] % 2 == 0): 172 | # if (rgb[p][j] != 0): 173 | # rgb[p][j] -= 1 174 | # print("2i=>", i, bi[i]) 175 | # i += 1 176 | # else: 177 | # rgb[p][j] += 1 178 | # print("3i=>", i, bi[i]) 179 | # i += 1 180 | # else: 181 | # print(bi[i],i) 182 | # i += 1 183 | # print("did not enter") 184 | # 185 | # print(rgb) 186 | # 187 | # print("done") 188 | --------------------------------------------------------------------------------