Пример #1
0
def quickEncrypt(event):
    global messageWindow
    inFile = openFunc(None)

    if inFile == None:
        print("Encryption Error: File Not Opened!")
        return

    #convert jpeg to png if needed
    if inFile[-4:] == ".jpg":
        im = Image.open(inFile)
        im.save(inFile[:-4] + ".png")
        inFile = (inFile[:-4] + ".png")

    setSecretWindow()

    while lock == 0:
        messageWindow.update_idletasks()
        messageWindow.update()

    outFile = filedialog.asksaveasfilename(defaultextension="png",
                                           initialdir='/',
                                           title='Save As...',
                                           filetypes=(("PNG files", "*.png"),
                                                      ("all files", "*.*")))

    if outFile:
        x = DCT()
        secret = x.DCTEn(inFile, quickMess, outFile)
    else:
        print('No filename given')
        return
Пример #2
0
def quickDecrypt(event):
    global deFile
    deFile = None

    deFile = openFunc(None)

    if deFile == None:
        print("Decryption Error: File Not Opened!")
        return

    #convert jpeg to png if needed
    if deFile[-4:] == ".jpg":
        print("Decrytion Error: File format not supported")
        return

    if deFile:
        y = DCT()
        decode = y.DCTDe(deFile)
    else:
        print('No filename given')
        return

    global messageWindow
    messageWindow = tk.Toplevel(root)

    l1 = tk.Label(messageWindow, text="Secret Message: " + decode)
    l1.pack()
    def __init__(self, image, quality, out, comment):
        self.quality = quality
        self.jpeg_obj = JpegInfo(image, comment)

        self.image_width, self.image_height = image.size
        self.out = out

        self.dct = DCT(self.quality)
        self.huf = Huffman(*image.size)
Пример #4
0
 def addDevice(self):
     try:
         device_info = input("Please Input Device name and Device type: ").strip().split(" ")
         types = ['i', 'I', 'o', 'O']
         # print(device_info)
         print("1.选择已有控制器; 2.创建新控制器")
         choose = int(input(">>"))
         if len(device_info) != 2:
             raise ValueError
         if device_info[1] not in types:
             raise ValueError
         if device_info[0] in self.device_table:
             raise NameError
     except ValueError:
         print("请检查输入!")
     except NameError:
         print("已存在同名设备,请重新输入设备名。")
     except:
         print("请检查输入")
     else:
         self.device_table.append(device_info[0])
         # sdt = SDT(name=device_info[0])
         dct = DCT(name=device_info[0], dtype=device_info[1])
         self.system_device_table.append(dct)  # 首先将新设备加入系统设备表
         # print("1.选择已有控制器; 2.创建新控制器")
         # choose = int(input(">>"))
         if choose == 1:
             co_name = input("输入控制器名: ")
             for i in range(len(self.CO_control_table)):
                 if self.CO_control_table[i].getName() == co_name:
                     dct.parent = self.CO_control_table[i]
             print("last_co: ", dct.parent)
         elif choose == 2:
             flag = True
             while flag:
                 co_name = input("输入新控制器名: ")
                 ch_name = input("输入选择的通道名称:")
                 if ch_name not in self.CH_table:
                     print("通道名输入错误,请重新输入!")
                 else:
                     flag = False
             new_co = COCT(name=co_name)
             dct.parent = new_co  # 新设备指向新的节点
             self.CO_control_table.append(new_co)  # 加入通道控制表
             for i in range(2):
                 if ch_name == self.CH_control_table[i].getName():
                     new_co.parent = self.CH_control_table[i]
     finally:
         pass
Пример #5
0
def decryptFn(event):
    global deFile
    global outBox
    global messageFrame

    if deFile:
        y = DCT()
        decode = y.DCTDe(deFile)
        outBox.config(state='normal')
        outBox.delete(0, 'end')
        outBox.insert(0, decode)
        outBox.config(state='disabled')
    else:
        print('No filename given')
        return
Пример #6
0
def encryptFn(event):
    global inFile
    global outFile
    global newImgFrame
    global endImage
    global inputBox

    outFile = filedialog.asksaveasfilename(defaultextension="png",
                                           initialdir='/',
                                           title='Save As...',
                                           filetypes=(("PNG files", "*.png"),
                                                      ("all files", "*.*")))

    if outFile:
        x = DCT()
        secretMess = inputBox.get()
        inputBox.delete(0, 'end')
        secret = x.DCTEn(inFile, secretMess, outFile)

        newImgFrame.pack_forget()
        if endImage:
            endImage.pack_forget()

        #resize image to fit in display viewer
        image = Image.open(outFile)
        newImgFrame = tk.Frame(imageFrame,
                               height=450,
                               width=300,
                               relief='ridge')
        newImgFrame.pack(side='right', padx=25, pady=25)

        basewidth = 300
        wpercent = (basewidth / float(image.size[0]))
        hsize = int((float(image.size[1]) * float(wpercent)))
        image = image.resize((basewidth, hsize), Image.ANTIALIAS)

        photo = ImageTk.PhotoImage(image)

        endImage = tk.Label(newImgFrame,
                            image=photo,
                            height=450,
                            width=300,
                            text='Encrypted Image')
        endImage.image = photo
        endImage.pack()
    else:
        print('No filename given')
        return
    def __init__(self, image, quality, out, comment):
        self.quality = quality
        self.jpeg_obj = JpegInfo(image, comment)

        self.image_width, self.image_height = image.size
        self.out = out

        self.dct = DCT(self.quality)
        self.huf = Huffman(*image.size)
Пример #8
0
def main_function(api):
    print(flask.request.values)
    # 文字
    text = flask.request.values.get('text')
    # 图像
    image = request.files['image']
    # 长度
    length = flask.request.values.get('length')
    # 格式
    format = flask.request.values.get('format')

    print('text:', text)
    print('image:', image)
    print('length:', length)
    print('format:', format)

    # 保存图片
    image_path = save_image(image)
    # 图片处理
    image_process = None
    if api == 'lsb':
        image_process = LSB(text, format, int(length))
    elif api == 'dct':
        image_process = DCT(text, format, int(length))
    msg_out1, msg_out2 = image_process.process(image_path)
    # 获取base64编码
    image_base64_1, image_base64_2 = return_base64(format)
    # 获取图像质量
    psnr, ssim = get_image_quality(format, image.filename)
    # json结果
    result = {}
    # 判断格式
    if format == 'jpg':
        result = {
            'msg_out': msg_out1,
            'image_base64_1': image_base64_1,
            'image_base64_2': image_base64_2,
            'psnr': psnr,
            'ssim': ssim
        }
    elif format == 'png':
        result = {
            'msg_out': msg_out2,
            'image_base64_1': image_base64_1,
            'image_base64_2': image_base64_2,
            'psnr': psnr,
            'ssim': ssim
        }
    # 处理跨域问题
    json_data = jsonify(result)
    res = make_response(json_data)
    res.headers['Access-Control-Allow-Origin'] = '*'
    # 删除本地图片
    delete_local_image('./embed')
    # 返回json数据
    return res
Пример #9
0
    def init(self):
        length = len(self.device_table)
        for i in range(length):
            # sdt = SDT(name=self.device_table[i])
            if i <= 1:
                # sdt.dct = DCT(name=self.device_table[i], dtype='I', pcb_name='job3')
                dct = DCT(name=self.device_table[i], dtype='I')
                # sdt.dct = dct
            else:
                dct = DCT(name=self.device_table[i])
                # sdt.dct = dct
            self.system_device_table.append(dct)

        self.system_device_table[0].parent = self.CO_control_table[0]
        self.system_device_table[1].parent = self.CO_control_table[0]
        self.CO_control_table[0].parent = self.CH_control_table[0]

        self.system_device_table[2].parent = self.CO_control_table[1]
        self.CO_control_table[1].parent = self.CH_control_table[1]

        self.system_device_table[3].parent = self.CO_control_table[2]
        self.CO_control_table[2].parent = self.CH_control_table[1]
Пример #10
0
class JpegEncoder(object):
    def __init__(self, image, quality, out, comment, ais):
        self.quality = quality
        self.jpeg_obj = JpegInfo(image, comment)

        self.image_width, self.image_height = image.size
        self.out = out

        self.dct = DCT(self.quality)
        self.huf = Huffman(*image.size)

        self.hasais = ais
        self.k_matrix = -1

    def compress(self, embedded_data=None, password='******'):
        self.embedded_data = EmbedData(
            embedded_data) if embedded_data else None
        self.password = password

        self.write_headers()
        self.write_compressed_data()
        self.write_eoi()
        self.out.flush()

    def get_quality(self):
        return self.quality

    def set_quality(self, quality):
        self.quality = quality
        self.dct = DCT(quality)

    def write_array(self, data):
        length = ((data[2] & 0xff) << 8) + (data[3] & 0xff) + 2
        self.out.write(bytearray(data[:length]))

    def write_marker(self, data):
        self.out.write(bytearray(data[:2]))

    def write_eoi(self):
        EOI = [0xff, 0xD9]
        self.write_marker(EOI)

    def write_headers(self):
        SOI = [0xff, 0xD8]
        self.write_marker(SOI)

        JFIF = [
            0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, 0x01,
            0x01, 0x00, 0x60, 0x00, 0x60, 0x00, 0x00
        ]
        self.write_array(JFIF)

        comment = self.jpeg_obj.get_comment()
        if comment:
            length = len(comment) + 2
            COM = [0xff, 0xfe, length >> 8 & 0xff, length & 0xff]
            COM.extend(comment)
            self.write_array(COM)

        DQT = [0xff, 0xdb, 0x00, 0x84]
        for k in range(2):
            DQT.append(k)
            DQT.extend([
                self.dct.quantum[k][JPEG_NATURAL_ORDER[i]] for i in range(64)
            ])
        self.write_array(DQT)

        SOF = [
            0xff, 0xc0, 0x00, 0x11, self.jpeg_obj.precision,
            self.jpeg_obj.image_height >> 8 & 0xff,
            self.jpeg_obj.image_height & 0xff,
            self.jpeg_obj.image_width >> 8 & 0xff,
            self.jpeg_obj.image_width & 0xff, self.jpeg_obj.comp_num
        ]
        for i in range(self.jpeg_obj.comp_num):
            SOF.append(self.jpeg_obj.com_id[i])
            SOF.append(
                eight_byte(self.jpeg_obj.hsamp_factor[i],
                           self.jpeg_obj.vsamp_factor[i]))
            SOF.append(self.jpeg_obj.qtable_number[i])
        self.write_array(SOF)

        DHT = [0xff, 0xc4, 0, 0]
        for i in range(4):
            DHT.extend(self.huf.BITS[i])
            DHT.extend(self.huf.VAL[i])

        DHT[2] = len(DHT) - 2 >> 8 & 0xff
        DHT[3] = len(DHT) - 2 & 0xff
        self.write_array(DHT)

        SOS = [0] * 14
        SOS = [0xff, 0xda, 0x00, 0x0c, self.jpeg_obj.comp_num]
        for i in range(self.jpeg_obj.comp_num):
            SOS.append(self.jpeg_obj.com_id[i])
            SOS.append(
                eight_byte(self.jpeg_obj.dctable_number[i],
                           self.jpeg_obj.actable_number[i]))

        SOS.append(self.jpeg_obj.ss)
        SOS.append(self.jpeg_obj.se)
        SOS.append(eight_byte(self.jpeg_obj.ah, self.jpeg_obj.al))
        self.write_array(SOS)

    def _get_coeff(self):
        dct_array1 = create_array(0.0, 8, 8)
        dct_array2 = create_array(0.0, 8, 8)
        dct_array3 = create_array(0, 64)

        coeff = []
        for r in range(min(self.jpeg_obj.block_height)):
            for c in range(min(self.jpeg_obj.block_width)):
                xpos = c * 8
                ypos = r * 8
                for comp in range(self.jpeg_obj.comp_num):
                    indata = self.jpeg_obj.components[comp]
                    maxa = self.image_height / 2 * self.jpeg_obj.vsamp_factor[
                        comp] - 1
                    maxb = self.image_width / 2 * self.jpeg_obj.hsamp_factor[
                        comp] - 1

                    for i in range(self.jpeg_obj.vsamp_factor[comp]):
                        for j in range(self.jpeg_obj.hsamp_factor[comp]):
                            ia = ypos * self.jpeg_obj.vsamp_factor[comp] + i * 8
                            ib = xpos * self.jpeg_obj.hsamp_factor[comp] + j * 8

                            for a in range(8):
                                for b in range(8):
                                    dct_array1[a][b] = indata[min(
                                        ia + a, maxa)][min(ib + b, maxb)]

                            dct_array2 = self.dct.forward_dct(dct_array1)
                            dct_array3 = self.dct.quantize_block(
                                dct_array2, self.jpeg_obj.qtable_number[comp])
                            coeff.extend(dct_array3[:64])
        return coeff

    def write_compressed_data(self):
        last_dc_value = create_array(0, self.jpeg_obj.comp_num)
        zero_array = create_array(0, 64)
        width, height = 0, 0
        min_block_width = min(self.jpeg_obj.block_width)
        min_block_height = min(self.jpeg_obj.block_height)

        logger.info('DCT/quantisation starts')
        logger.info('%d x %d' % (self.image_width, self.image_height))

        coeff = self._get_coeff()  #量化后的系数,是整数
        coeff_count = len(coeff)

        #导出未处理的QDCT
        if self.hasais:
            filename = 'unpro_ais.json'
        else:
            filename = 'unpro.json'
        with open(filename, 'w') as f_unprocess:
            json.dump(coeff, f_unprocess)

        #AIS处理
        if self.hasais:
            size_secret = self.embedded_data.len
            ais = Ais(coeff, size_secret)  #coeff被修改
            ais.statistic()
            self.k_matrix = ais.fix()
            with open('aised.json', 'w') as f_aised:
                json.dump(coeff, f_aised)

        #嵌入——>再统计嵌入后的数据,决定是否继续做AIS处理
        logger.info('got %d DCT AC/DC coefficients' % coeff_count)
        _changed, _embedded, _examined, _expected, _one, _large, _thrown, _zero = 0, 0, 0, 0, 0, 0, 0, 0
        shuffled_index = 0
        for i, cc in enumerate(coeff):
            if i % 64 == 0:
                continue
            if cc == 1 or cc == -1:
                _one += 1
            elif cc == 0:
                _zero += 1

        _large = coeff_count - _zero - _one - coeff_count / 64  #有效系数的个数
        _expected = _large + int(0.49 * _one)  #预期容量,shrinkage效应无法确定

        logger.info('one=%d' % _one)
        logger.info('large=%d' % _large)
        logger.info('\nexpected capacity: %d bits\n' % _expected)
        logger.info('expected capacity with')

        for i in range(1, 8):
            n = (1 << i) - 1  #n=2^i-1
            changed = _large - _large % (n + 1)
            changed = (changed + _one + _one / 2 - _one / (n + 1)) / (n + 1)
            usable = (_expected * i / n - _expected * i / n % n) / 8
            if usable == 0:
                break

            logger.info(
                '%s code: %d bytes (efficiency: %d.%d bits per change)' %
                ('default' if i == 1 else '(1, %d, %d)' % (n, i), usable,
                 usable * 8 / changed, usable * 80 / changed % 10))

        #shuffles all coefficients using a permutation,使用排列对系数进行混洗
        if self.embedded_data is not None:
            logger.info('permutation starts')
            random = F5Random(self.password)
            permutation = Permutation(coeff_count, random)

            next_bit_to_embed = 0
            byte_to_embed = len(self.embedded_data)
            available_bits_to_embed = 0

            logger.info('Embedding of %d bits (%d+4 bytes)' %
                        (byte_to_embed * 8 + 32, byte_to_embed))

            if byte_to_embed > 0x007fffff:
                byte_to_embed = 0x007ffff

            for i in range(1, 8):
                self.n = (1 << i) - 1
                usable = (_expected * i / self.n -
                          _expected * i / self.n % self.n) / 8
                if usable < byte_to_embed + 4:
                    break

            #确定(1,n,k)
            if self.k_matrix < 0:
                k = i - 1
            else:
                k = self.k_matrix
            self.n = (1 << k) - 1

            if self.n == 0:
                logger.info('using default code, file will not fit')
                self.n = 1
            elif self.n == 1:
                logger.info('using default code')
            else:
                logger.info('using (1, %d, %d) code' % (self.n, k))

            byte_to_embed |= k << 24
            byte_to_embed ^= random.get_next_byte()
            byte_to_embed ^= random.get_next_byte() << 8
            byte_to_embed ^= random.get_next_byte() << 16
            byte_to_embed ^= random.get_next_byte() << 24

            next_bit_to_embed = byte_to_embed & 1
            byte_to_embed >>= 1
            available_bits_to_embed = 31
            _embedded += 1

            for i, shuffled_index in enumerate(permutation.shuffled):
                if shuffled_index % 64 == 0 or coeff[shuffled_index] == 0:
                    continue
                cc = coeff[shuffled_index]
                _examined += 1

                if cc > 0 and (cc & 1) != next_bit_to_embed:
                    coeff[shuffled_index] -= 1
                    _changed += 1
                elif cc < 0 and (cc & 1) == next_bit_to_embed:
                    coeff[shuffled_index] += 1
                    _changed += 1

                if coeff[shuffled_index] != 0:
                    if available_bits_to_embed == 0:
                        if self.n > 1 or not self.embedded_data.available():
                            break
                        byte_to_embed = self.embedded_data.read()
                        byte_to_embed ^= random.get_next_byte()
                        available_bits_to_embed = 8
                    next_bit_to_embed = byte_to_embed & 1
                    byte_to_embed >>= 1
                    available_bits_to_embed -= 1
                    _embedded += 1
                else:
                    _thrown += 1

            if self.n > 1:
                try:
                    is_last_byte = False
                    filtered_index = FilteredCollection(
                        permutation.shuffled[i + 1:],
                        lambda index: index % 64 and coeff[index])
                    while not is_last_byte:
                        k_bits_to_embed = 0
                        for i in range(k):
                            if available_bits_to_embed == 0:
                                if not self.embedded_data.available():
                                    is_last_byte = True
                                    break
                                byte_to_embed = self.embedded_data.read()
                                byte_to_embed ^= random.get_next_byte()
                                available_bits_to_embed = 8
                            next_bit_to_embed = byte_to_embed & 1
                            byte_to_embed >>= 1
                            available_bits_to_embed -= 1
                            k_bits_to_embed |= next_bit_to_embed << i
                            _embedded += 1

                        code_word = filtered_index.offer(self.n)
                        while True:
                            vhash = 0
                            for i, index in enumerate(code_word):
                                if coeff[index] > 0:
                                    extracted_bit = coeff[index] & 1
                                else:
                                    extracted_bit = 1 - (coeff[index] & 1)
                                if extracted_bit == 1:
                                    vhash ^= i + 1
                            i = vhash ^ k_bits_to_embed
                            if not i:
                                break

                            i -= 1
                            coeff[code_word[i]] += 1 if coeff[
                                code_word[i]] < 0 else -1
                            _changed += 1

                            if not coeff[code_word[i]]:
                                _thrown += 1
                                code_word[i:i + 1] = []
                                code_word.extend(filtered_index.offer(1))
                            else:
                                break
                except FilteredCollection.ListNotEnough:
                    pass

            if _examined > 0:
                logger.info('%d coefficients examined' % _examined)
            if _changed > 0:
                logger.info(
                    '%d coefficients changed (efficiency: %d.%d bits per change'
                    % (_changed, _embedded / _changed,
                       _embedded * 10 / _changed % 10))
            logger.info('%d coefficients thrown (zeroed)' % _thrown)
            logger.info('%d bits (%d bytes) embedded' %
                        (_embedded, _embedded / 8))

        #导出嵌入后的系数coeff
        if self.hasais:
            filename2 = 'embeded_ais.json'
        else:
            filename2 = 'embeded.json'
        with open(filename2, 'w') as f_embeded:
            json.dump(coeff, f_embeded)

        logger.info('starting hufman encoding')
        shuffled_index = 0

        for r in range(min_block_height):
            for c in range(min_block_width):
                for comp in range(self.jpeg_obj.comp_num):
                    for i in range(self.jpeg_obj.vsamp_factor[comp]):
                        for j in range(self.jpeg_obj.hsamp_factor[comp]):
                            dct_array3 = coeff[shuffled_index:shuffled_index +
                                               64]
                            self.huf.huffman_block_encoder(
                                self.out, dct_array3, last_dc_value[comp],
                                self.jpeg_obj.dctable_number[comp],
                                self.jpeg_obj.actable_number[comp])
                            last_dc_value[comp] = dct_array3[0]
                            shuffled_index += 64

        self.huf.flush_buffer(self.out)
        logger.info('hufman encode end')
Пример #11
0
 def set_quality(self, quality):
     self.quality = quality
     self.dct = DCT(quality)
Пример #12
0
from DCT import DCT
from Image import Image
from Grafico import Grafico

dct = DCT()
img = Image()
#grafico = Grafico()

sDigital = [10, 5, 8.5, 2, 1, 1.5, 0, 0.1]     #   Sinal Digital
print('Sinal original')
print(sDigital)

sAnalogico = dct.idct(sDigital)
print(sAnalogico)

sDigital = dct.dct(sAnalogico)
print(sDigital)
Пример #13
0
def lsbAlgoStegano(type, secret_string, encrypt_decrypt, encryption_technique):
    if (encrypt_decrypt == options[0]):
        if (len(secret_string) == 1):
            print("Empty Secret:: Showing warning")
            tk.messagebox.showwarning(
                "Data Required", "Please enter secret data to be encoded")
            return
    if (type == "DCT"):
        if (encrypt_decrypt == options[0]):
            file_name = encryption_technique + "DCT.txt"
            text_file = open(file_name, "w")
            text_file.write(str(secret_string))
            text_file.close
            if encryption_technique == "OTP":
                enc = OneTimePad(secret_string, "DCT")
                enc_string = enc.run(encrypt_decrypt)

            elif encryption_technique == "RSA":
                enc = RSACipher(secret_string, "DCT")
                enc_string = enc.run(encrypt_decrypt)

            elif encryption_technique == "AES":
                enc = AESCipher(secret_string, "DCT")
                enc_string = enc.run(encrypt_decrypt)

            elif encryption_technique == "DES":
                enc = DESCipher(secret_string, "DCT")
                enc_string = enc.run(encrypt_decrypt)

            outFile = "secret/secretDCT.png"
            x = DCT(image_path)
            secret = x.DCTEn(enc_string, outFile)
            print("secret :: DCT:: ", secret)
            # secret = red.hide(image_path, secret_string)
            # secret.save("secret.png")
            displayImage("secret/secretDCT.png")
            img1 = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
            print(img1.shape)
            img2 = cv2.imread("secret/secretDCT.png", cv2.IMREAD_UNCHANGED)
            print(img1.shape, img2.shape)
            if is_grey_scale(image_path) and len(img2.shape) == 3:
                imgA = cv2.cvtColor(img1, cv2.COLOR_BGRA2GRAY)
                imgB = cv2.cvtColor(img2, cv2.COLOR_BGRA2GRAY)
            else:
                imgA = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
                imgB = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
            compare_images(imgA, imgB, "DCT", encryption_technique)
        else:
            y = DCT(image_path)
            secret = y.DCTDe()
            # secret = red.reveal(image_path)
            print("Secret is ", secret)
            if encryption_technique == "OTP":
                dec = OneTimePad(secret, "DCT")
                secret_message = dec.run(encrypt_decrypt)

            elif encryption_technique == "RSA":
                dec = RSACipher(secret, "DCT")
                secret_message = dec.run(encrypt_decrypt)

            elif encryption_technique == "AES":
                dec = AESCipher(secret, "DCT")
                secret_message = dec.run(encrypt_decrypt)

            elif encryption_technique == "DES":
                dec = DESCipher(secret, "DCT")
                secret_message = dec.run(encrypt_decrypt)

            #dec = OneTimePad(secret, "DCT")
            #secret_message = dec.run(encrypt_decrypt)
            filename = encryption_technique + "DCT.txt"
            key_file = open(filename, "r")
            original_message = key_file.readline()
            key_file.close()
            precentage_comparison = compare_strings(original_message,
                                                    secret_message)
            print("The strings are equal by", precentage_comparison, "parts")
            addtofile("DCT", encryption_technique[:3], precentage_comparison)
            displaySecret(secret_message)
            saveSecretToFile(secret_message)
Пример #14
0
def main():
    args = parser()

    algo = args.algorithm
    inFile = args.inputfile
    message = args.string
    outFile = args.outputfile
    msgFile = args.file

    #encryption input check
    if args.encrypt is True and args.string is None and args.file is None:
        raise ValueError("Encryption requires an input string")

    # read file msg
    if args.file is not None:
        with open(msgFile, 'r') as textFile:
            message = textFile.read().replace('\n', '')

    #encryption
    if args.encrypt:

        #set output file if not specified
        if not args.outputfile:
            rawName = os.path.basename(os.path.normpath(inFile))
            dirName = os.path.dirname(os.path.normpath(inFile))

            outFile = dirName + '/' + algo + rawName

        #LSB implementation
        if algo == "LSB":
            start = time.time()
            x = LSB(inFile)
            encoded = x.hide(message, outFile)
            end = time.time() - start
            print('time: ')
            print(end)
            #print ('Message encoded = ' + x.message)
        else:
            #DCT implementation
            start = time.time()
            x = DCT(inFile)
            secret = x.DCTEn(message, outFile)
            end = time.time() - start
            print('time: ')
            print(end)
            #print('Message encoded = '+ x.message)

    #decryption
    else:
        #LSB implementation
        if algo == 'LSB':
            start = time.time()
            y = LSB(inFile)
            secret = y.extract()
            end = time.time() - start
            print('Hidden Message:\n' + secret)
            print('time: ')
            print(end)
        else:
            #DCT implementation
            start = time.time()
            y = DCT(inFile)
            decode = y.DCTDe()
            end = time.time() - start
            print('Hidden Message:\n' + decode)
            print('time: ')
            print(end)
class JpegEncoder(object):
    def __init__(self, image, quality, out, comment):
        self.quality = quality
        self.jpeg_obj = JpegInfo(image, comment)

        self.image_width, self.image_height = image.size
        self.out = out

        self.dct = DCT(self.quality)
        self.huf = Huffman(*image.size)

    def compress(self, embedded_data=None, password='******'):
        self.embedded_data = EmbedData(embedded_data) if embedded_data else None
        self.password = password

        self.write_headers()
        self.write_compressed_data()
        self.write_eoi()
        self.out.flush()

    def get_quality(self):
        return self.quality

    def set_quality(self, quality):
        self.quality = quality
        self.dct = DCT(quality)

    def write_array(self, data):
        length = ((data[2] & 0xff) << 8) + (data[3] & 0xff) + 2
        self.out.write(bytearray(data[:length]))

    def write_marker(self, data):
        self.out.write(bytearray(data[:2]))

    def write_eoi(self):
        EOI = [0xff, 0xD9]
        self.write_marker(EOI)

    def write_headers(self):
        SOI = [0xff, 0xD8]
        self.write_marker(SOI)

        JFIF = [0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 
                0x49, 0x46, 0x00, 0x01, 0x01, 0x01, 
                0x00, 0x60, 0x00, 0x60, 0x00, 0x00]
        self.write_array(JFIF)

        comment = self.jpeg_obj.get_comment()
        if comment:
            length = len(comment) + 2
            COM = [0xff, 0xfe, length >> 8 & 0xff, length & 0xff]
            COM.extend(comment)
            self.write_array(COM)

        DQT = [0xff, 0xdb, 0x00, 0x84]
        for k in range(2):
            DQT.append(k)
            DQT.extend([self.dct.quantum[k][JPEG_NATURAL_ORDER[i]] for i in range(64)])
        self.write_array(DQT)

        SOF = [0xff, 0xc0, 0x00, 0x11, 
                self.jpeg_obj.precision, 
                self.jpeg_obj.image_height >> 8 & 0xff, 
                self.jpeg_obj.image_height & 0xff, 
                self.jpeg_obj.image_width >> 8 & 0xff, 
                self.jpeg_obj.image_width & 0xff, 
                self.jpeg_obj.comp_num]
        for i in range(self.jpeg_obj.comp_num):
            SOF.append(self.jpeg_obj.com_id[i])
            SOF.append(eight_byte(self.jpeg_obj.hsamp_factor[i], self.jpeg_obj.vsamp_factor[i]))
            SOF.append(self.jpeg_obj.qtable_number[i])
        self.write_array(SOF)
        
        DHT = [0xff, 0xc4, 0, 0]
        for i in range(4):
            DHT.extend(self.huf.BITS[i])
            DHT.extend(self.huf.VAL[i])

        DHT[2] = len(DHT) - 2 >> 8 & 0xff
        DHT[3] = len(DHT) - 2 & 0xff
        self.write_array(DHT)

        SOS = [0] * 14
        SOS = [0xff, 0xda, 0x00, 0x0c, self.jpeg_obj.comp_num]
        for i in range(self.jpeg_obj.comp_num):
            SOS.append(self.jpeg_obj.com_id[i])
            SOS.append(eight_byte(self.jpeg_obj.dctable_number[i], self.jpeg_obj.actable_number[i]))

        SOS.append(self.jpeg_obj.ss)
        SOS.append(self.jpeg_obj.se)
        SOS.append(eight_byte(self.jpeg_obj.ah, self.jpeg_obj.al))
        self.write_array(SOS)

    def _get_coeff(self):
        dct_array1 = create_array(0.0, 8, 8)
        dct_array2 = create_array(0.0, 8, 8)
        dct_array3 = create_array(0, 64)

        coeff = []
        for r in range(min(self.jpeg_obj.block_height)):
            for c in range(min(self.jpeg_obj.block_width)):
                xpos = c * 8
                ypos = r * 8
                for comp in range(self.jpeg_obj.comp_num):
                    indata = self.jpeg_obj.components[comp]
                    maxa = self.image_height / 2 * self.jpeg_obj.vsamp_factor[comp] - 1
                    maxb = self.image_width / 2 * self.jpeg_obj.hsamp_factor[comp] - 1

                    for i in range(self.jpeg_obj.vsamp_factor[comp]):
                        for j in range(self.jpeg_obj.hsamp_factor[comp]):
                            ia = ypos * self.jpeg_obj.vsamp_factor[comp] + i * 8
                            ib = xpos * self.jpeg_obj.hsamp_factor[comp] + j * 8

                            for a in range(8):
                                for b in range(8):
                                    dct_array1[a][b] = indata[min(ia+a, maxa)][min(ib+b, maxb)]

                            dct_array2 = self.dct.forward_dct(dct_array1)
                            dct_array3 = self.dct.quantize_block(dct_array2, 
                                    self.jpeg_obj.qtable_number[comp])
                            coeff.extend(dct_array3[:64])
        return coeff

    def write_compressed_data(self):
        tmp = 0

        last_dc_value = create_array(0, self.jpeg_obj.comp_num)
        zero_array = create_array(0, 64)
        width, height = 0, 0

        min_block_width = min(self.jpeg_obj.block_width)
        min_block_height = min(self.jpeg_obj.block_height)

        logger.info('DCT/quantisation starts')
        logger.info('%d x %d' % (self.image_width, self.image_height))

        coeff = self._get_coeff()
        coeff_count = len(coeff)

        logger.info('got %d DCT AC/DC coefficients' % coeff_count)
        _changed, _embedded, _examined, _expected, _one, _large, _thrown, _zero = 0, 0, 0, 0, 0, 0, 0, 0
        shuffled_index = 0
        for i, cc in enumerate(coeff):
            if i % 64 == 0:
                continue
            if cc == 1 or cc == -1:
                _one += 1
            elif cc == 0:
                _zero += 1

        _large = coeff_count - _zero - _one - coeff_count / 64
        _expected = _large + int(0.49 * _one)

        logger.info('one=%d' % _one)
        logger.info('large=%d' % _large)

        logger.info('expected capacity: %d bits' % _expected)
        logger.info('expected capacity with')
        for i in range(1, 8):
            n = (1 << i) - 1
            changed = _large - _large % (n + 1)
            changed = (changed + _one + _one / 2 - _one / (n + 1)) / (n + 1)

            usable = (_expected * i / n - _expected * i / n % n) / 8
            if usable == 0:
                break

            logger.info('%s code: %d bytes (efficiency: %d.%d bits per change)' % ('default' if i == 1 else '(1, %d, %d)' % (n, i), usable, usable * 8 / changed, usable * 80 / changed % 10))

        if self.embedded_data is not None:
            logger.info('permutation starts')
            random = F5Random(self.password)
            permutation = Permutation(coeff_count, random)

            next_bit_to_embed = 0
            byte_to_embed = len(self.embedded_data)
            available_bits_to_embed = 0

            logger.info('Embedding of %d bits (%d+4 bytes)' % (byte_to_embed * 8 + 32, byte_to_embed))

            if byte_to_embed > 0x007fffff:
                byte_to_embed = 0x007ffff

            for i in range(1, 8):
                self.n = (1 << i) - 1
                usable = (_expected * i / self.n - _expected * i / self.n % self.n) / 8
                if usable < byte_to_embed + 4:
                    break

            k = i - 1
            self.n = (1 << k) - 1

            if self.n == 0:
                logger.info('using default code, file will not fit')
                self.n = 1
            elif self.n == 1:
                logger.info('using default code')
            else:
                logger.info('using (1, %d, %d) code' % (self.n, k))

            byte_to_embed |= k << 24
            byte_to_embed ^= random.get_next_byte()
            byte_to_embed ^= random.get_next_byte() << 8
            byte_to_embed ^= random.get_next_byte() << 16
            byte_to_embed ^= random.get_next_byte() << 24

            next_bit_to_embed = byte_to_embed & 1
            byte_to_embed >>= 1
            available_bits_to_embed = 31
            _embedded += 1

            for i, shuffled_index in enumerate(permutation.shuffled):
                if shuffled_index % 64 == 0 or coeff[shuffled_index] == 0:
                    continue
                cc = coeff[shuffled_index]
                _examined += 1

                if cc > 0 and (cc & 1) != next_bit_to_embed:
                    coeff[shuffled_index] -= 1
                    _changed +=1
                elif cc < 0 and (cc & 1) == next_bit_to_embed:
                    coeff[shuffled_index] += 1
                    _changed += 1

                if coeff[shuffled_index] != 0:
                    if available_bits_to_embed == 0:
                        if self.n > 1 or not self.embedded_data.available():
                            break
                        byte_to_embed = self.embedded_data.read()
                        byte_to_embed ^= random.get_next_byte()
                        available_bits_to_embed = 8
                    next_bit_to_embed = byte_to_embed & 1
                    byte_to_embed >>= 1
                    available_bits_to_embed -= 1
                    _embedded += 1
                else:
                    _thrown += 1

            if self.n > 1:
                try:
                    is_last_byte = False
                    filtered_index = FilteredCollection(permutation.shuffled[i+1:], lambda index: index % 64 and coeff[index])
                    while not is_last_byte:
                        k_bits_to_embed = 0
                        for i in range(k):
                            if available_bits_to_embed == 0:
                                if not self.embedded_data.available():
                                    is_last_byte = True
                                    break
                                byte_to_embed = self.embedded_data.read()
                                byte_to_embed ^= random.get_next_byte()
                                available_bits_to_embed = 8
                            next_bit_to_embed = byte_to_embed & 1
                            byte_to_embed >>= 1
                            available_bits_to_embed -= 1
                            k_bits_to_embed |= next_bit_to_embed << i
                            _embedded += 1

                        code_word = filtered_index.offer(self.n)
                        while True:
                            vhash = 0
                            for i, index in enumerate(code_word):
                                if coeff[index] > 0:
                                    extracted_bit = coeff[index] & 1
                                else:
                                    extracted_bit = 1 - (coeff[index] & 1)
                                if extracted_bit == 1:
                                    vhash ^= i + 1
                            i = vhash ^ k_bits_to_embed
                            if not i:
                                break

                            i -= 1
                            coeff[code_word[i]] += 1 if coeff[code_word[i]] < 0 else -1
                            _changed += 1

                            if not coeff[code_word[i]]:
                                _thrown += 1
                                code_word[i:i+1] = []
                                code_word.extend(filtered_index.offer(1))
                            else:
                                break
                except FilteredCollection.ListNotEnough:
                    pass

            if _examined > 0:
                logger.info('%d coefficients examined' % _examined)
            if _changed > 0:
                logger.info('%d coefficients changed (efficiency: %d.%d bits per change' % (_changed, _embedded / _changed, _embedded * 10 / _changed % 10))
            logger.info('%d coefficients thrown (zeroed)' % _thrown)
            logger.info('%d bits (%d bytes) embedded' % (_embedded, _embedded / 8))

        logger.info('starting hufman encoding')
        shuffled_index = 0

        for r in range(min_block_height):
            for c in range(min_block_width):
                for comp in range(self.jpeg_obj.comp_num):
                    for i in range(self.jpeg_obj.vsamp_factor[comp]):
                        for j in range(self.jpeg_obj.hsamp_factor[comp]):
                            dct_array3 = coeff[shuffled_index:shuffled_index+64]
                            self.huf.huffman_block_encoder(self.out, dct_array3, last_dc_value[comp],
                                    self.jpeg_obj.dctable_number[comp], self.jpeg_obj.actable_number[comp])
                            last_dc_value[comp] = dct_array3[0]
                            shuffled_index += 64
        
        self.huf.flush_buffer(self.out)
 def set_quality(self, quality):
     self.quality = quality
     self.dct = DCT(quality)