{"cells":[{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport os\nimport matplotlib.pyplot as plt\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"base = '/kaggle/input/alaska2-image-steganalysis/'\nid = '{:05d}'.format(20) \n\ncover_path = os.path.join(base, 'Cover', id + '.jpg')\n\nimg = plt.imread(cover_path)\n\nplt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"cover_path","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Encode the data:\n\nEvery byte of data is converted to its 8-bit binary code using ASCII values. Now pixels are read from left to right in a group of 3 containing a total of 9 values. The first 8-values are used to store the binary data. The value is made odd, if 1 occurs and even, if 0 occurs. "},{"metadata":{},"cell_type":"markdown","source":"# For example : \nSuppose the message to be hidden is ‘ Hii ‘. Since the message is of 3-bytes, therefore, pixels required to encode the data is 3 x 3 = 9. Consider a 4 x 3 image with total 12-pixels, which are sufficient to encode the given data.\n[(27, 64, 164), (248, 244, 194), (174, 246, 250), (149, 95, 232),\n(188, 156, 169), (71, 167, 127), (132, 173, 97), (113, 69, 206),\n(255, 29, 213), (53, 153, 220), (246, 225, 229), (142, 82, 175)]\n\n\nASCII value of ‘ H ‘ is 72 whose binary equivalent is 01001000."},{"metadata":{},"cell_type":"markdown","source":"Taking first 3-pixels (27, 64, 164), (248, 244, 194), (174, 246, 250) to encode. Now change the pixel to odd for 1 and even for 0. So, the modifies pixels are (26, 63, 164), (248, 243, 194), (174, 246, 250). Since we have to encode more data, therefore, the last value should be even. Similarly, ‘i‘ can be encoded in this image.\n\nThe new image will look like :\n\n[(26, 63, 164), (248, 243, 194), (174, 246, 250), (148, 95, 231),\n(188, 155, 168), (70, 167, 126), (132, 173, 97), (112, 69, 206),\n(254, 29, 213), (53, 153, 220), (246, 225, 229), (142, 82, 175)]"},{"metadata":{},"cell_type":"markdown","source":"Decode the data :\nTo decode, three pixels are read at a time, till the last value is odd, which means the message is over. Every 3-pixels contain a binary data, which can be extracted by the same encoding logic. If the value if odd the binary bit is 1 else 0."},{"metadata":{"trusted":true},"cell_type":"code","source":"from PIL import Image \n  \n# Convert encoding data into 8-bit binary \n# form using ASCII value of characters \ndef genData(data): \n          \n        # list of binary codes \n        # of given data \n        newd = []  \n          \n        for i in data: \n            newd.append(format(ord(i), '08b')) \n        return newd \n          \n# Pixels are modified according to the \n# 8-bit binary data and finally returned \ndef modPix(pix, data): \n      \n    datalist = genData(data) \n    lendata = len(datalist) \n    imdata = iter(pix) \n  \n    for i in range(lendata): \n          \n        # Extracting 3 pixels at a time \n        pix = [value for value in imdata.__next__()[:3] +\n                                  imdata.__next__()[:3] +\n                                  imdata.__next__()[:3]] \n                                      \n        # Pixel value should be made  \n        # odd for 1 and even for 0 \n        for j in range(0, 8): \n            if (datalist[i][j]=='0') and (pix[j]% 2 != 0): \n                  \n                if (pix[j]% 2 != 0): \n                    pix[j] -= 1\n                      \n            elif (datalist[i][j] == '1') and (pix[j] % 2 == 0): \n                pix[j] -= 1\n                  \n        # Eigh^th pixel of every set tells  \n        # whether to stop ot read further. \n        # 0 means keep reading; 1 means the \n        # message is over. \n        if (i == lendata - 1): \n            if (pix[-1] % 2 == 0): \n                pix[-1] -= 1\n        else: \n            if (pix[-1] % 2 != 0): \n                pix[-1] -= 1\n  \n        pix = tuple(pix) \n        yield pix[0:3] \n        yield pix[3:6] \n        yield pix[6:9] \n  \ndef encode_enc(newimg, data): \n    w = newimg.size[0] \n    (x, y) = (0, 0) \n      \n    for pixel in modPix(newimg.getdata(), data): \n          \n        # Putting modified pixels in the new image \n        newimg.putpixel((x, y), pixel) \n        if (x == w - 1): \n            x = 0\n            y += 1\n        else: \n            x += 1\n            \n    return newimg \n              \n# Encode data into image \ndef encode(): \n    img = input(\"Enter image name(with extension): \") \n    image = Image.open(img, 'r') \n      \n    data = input(\"Enter data to be encoded : \") \n    if (len(data) == 0): \n        raise ValueError('Data is empty') \n          \n    newimg = image.copy() \n    img = encode_enc(newimg, data) \n      \n    plt.imshow(img)\n    \n  \n# Decode the data in the image \ndef decode(): \n    img = input(\"Enter image name(with extension) :\") \n    image = Image.open(img, 'r') \n      \n    data = '' \n    imgdata = iter(image.getdata()) \n      \n    while (True): \n        pixels = [value for value in imgdata.__next__()[:3] +\n                                  imgdata.__next__()[:3] +\n                                  imgdata.__next__()[:3]] \n        # string of binary data \n        binstr = '' \n          \n        for i in pixels[:8]: \n            if (i % 2 == 0): \n                binstr += '0'\n            else: \n                binstr += '1'\n                  \n        data += chr(int(binstr, 2)) \n        if (pixels[-1] % 2 != 0): \n            return data \n              \n# Main Function         \ndef main(): \n    a = int(input(\":: Welcome to Steganography ::\\n\"\n                        \"1. Encode\\n 2. Decode\\n\")) \n    if (a == 1): \n        encode() \n          \n    elif (a == 2): \n        print(\"Decoded word- \" + decode()) \n    else: \n        raise Exception(\"Enter correct input\") \n          \n# Driver Code \nif __name__ == '__main__' : \n      \n    # Calling main function \n    main() ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}