用python实现图种生成器

本文档介绍了一个名为imgSeed.py的模块,该模块能够将秘密文件隐藏在任何其他可见文件中,实现秘密文件的传输。通过附加或编码隐藏文件,使其在覆盖文件中变得不可见,除非知道其存在。支持多种编码方法,如Base16、Base32、Base64等。提供了`zipfile`和`unzip`两个主要函数,用于文件的隐藏和解隐藏操作。
摘要由CSDN通过智能技术生成

自己写了一个名为 “imgSeed.py” 的模块,可以生成图种,也可以从图种中分离出文件。

import os
import base64
import time
__doc__ = """
This module aims at secret file transmission by attaching a secret file to 
a cover file. By doing so, the secret file will be hidden in the cover file
and becomes invisible unless you know what it is.

Example:
import imgSeed
imgSeed.zipfile('cover.png', 'hidden.rar', out='output.png')  # No encoding
# Without encoding, you can get the hidden file by merely changing it's extension
# into a proper form (here is '.rar'). Also, you can get the original file by
# using unzip function in this module.

imgSeed.zipfile('cover.png', 'hidden.rar', method='base64')  # Encode by base64
imgSeed.unzip('output.png')  # Decode the file
# With encoding, you need to use the unzip function in this module to decode 
# the hidden file so that you can get it.
"""
__all__ = ['zipfile', 'unzip']
__methods__ = ['base16', 'base32', 'base64', 'ascii85', 'encodebytes']


def zipfile(cover, hidden, out=None, method=None):
    """
    To hide a private file in any other file. You can encode the hidden file
    then link it to the cover file. Also, you can merely link it to the cover file
    directly without encoding, in order that you can read the hidden file
    by changing it's extension into a proper form, which is so called image seed
    also Tu Zhong in Chinese. You can find the output file in the given path or cover file's path.

    :param cover: the cover file, which is visible.
    :param hidden: the file to be hidden in the cover file.
    :param out: the output file whose extension is the same as cover file's.
    :param method: the method to encode the hidden file.
    :return: None
    """
    def encode(method_):
        """
        To encrypt the private file then link it to anther file.

        :param method_: equal to the previous parameter 'method'.
        :return: None
        """
        print('Linking...')
        methods = {'b16': (base64.b16encode, 'base16'), 'base16': (base64.b16encode, 'base16'),
                   'b32': (base64.b32encode, 'base32'), 'base32': (base64.b32encode, 'base32'),
                   'b64': (base64.b64encode, 'base64'), 'base64': (base64.b64encode, 'base64'),
                   'a85': (base64.a85encode, 'base85'), 'ascii85': (base64.a85encode, 'ascii85'),
                   'eb': (base64.encodebytes, 'encodebytes'), 'encodebytes': (base64.encodebytes, 'encodebytes')}
        with open(cover, 'rb') as reader:
            cover_byte = reader.read()
        with open(hidden, 'rb') as reader:
            hidden_byte = reader.read()
        num = 0
        output_name = os.path.split(out)[1] if out else 'output'
        output_path = os.path.split(out)[0] if out else '.'
        if not os.path.exists(output_path):
            output_path = '.'
        output_ext = os.path.splitext(output_name)[1]
        output_ext = output_ext if output_ext else os.path.splitext(cover)[1]
        while True:
            outfile = os.path.join(output_path, output_name + ('' if num == 0 else str(num)) + output_ext)
            if os.path.exists(outfile):
                num += 1
            else:
                break
        method_ = methods[method_][1] if method_ in methods else None
        hidden_byte = methods[method_][0](hidden_byte) if method_ else hidden_byte
        cover_size = len(cover_byte)
        hidden_size = len(hidden_byte)
        file_info = (str(f'method={method_}&f1={cover_paths[1]}&f2={os.path.split(hidden)[1]}&f1_size={cover_size}&f2_size={hidden_size}\n')).encode('utf-8')
        content = cover_byte + hidden_byte + file_info
        with open(outfile, 'wb') as writer:
            writer.write(content)
        print('Done.')

    if not os.path.exists(cover):
        print(f'"{cover}" is not found.')
        return
    if not os.path.isfile(cover):
        print(f'"{cover}" is not a file.')
        return
    cover_paths = os.path.split(cover)
    if os.path.exists(hidden):
        encode(str(method).lower())
    elif os.path.exists(os.path.join(cover_paths[0], hidden)):
        encode(str(method).lower())
    else:
        print(f'"{hidden}" is not found.')


def unzip(file, out=os.getcwd()):
    """
    Get the original files. To divide the given file, which is generated by
    the zipfile function in this module, into a cover file and a hidden file.

    :param file: the path of the file to be divided.
    :param out: the output directory.
    :return: None
    """
    if not os.path.exists(file):
        print(f'"{file}" is not found.')
        return
    print('Separating...')
    with open(file, 'rb') as reader:
        lines = reader.readlines()[-1]
        index = lines.index(b'method')
        file_info = lines[index:]
        reader.seek(0)
        content_byte = reader.read()[:-len(file_info)]
    date = time.strftime(' %Y-%m-%d_%H-%M-%S')
    info = {kw.split('=')[0].strip(): kw.split('=')[1].strip() for kw in file_info.decode('utf-8').split('&')}
    methods = {'b16': base64.b16decode, 'base16': base64.b16decode,
               'b32': base64.b32decode, 'base32': base64.b32decode,
               'b64': base64.b64decode, 'base64': base64.b64decode,
               'a85': base64.a85decode, 'ascii85': base64.a85decode,
               'eb': base64.decodebytes, 'encodebytes': base64.decodebytes}
    file1 = os.path.splitext(info['f1'])
    file1_size = int(info['f1_size'])
    file2 = os.path.splitext(info['f2'])
    file2_size = int(info['f2_size'])
    if not os.path.exists(out):
        out = '.'
    with open(os.path.join(out, date.join(file1)), 'wb') as writer:
        writer.write(content_byte[:file1_size])
    with open(os.path.join(out, date.join(file2)), 'wb') as writer:
        if info['method'] in methods:
            writer.write(methods[info['method']](content_byte[-file2_size:]))
        else:
            writer.write(content_byte[-file2_size:])
        print('Done!')


def main():
    pass


if __name__ == '__main__':
    main()

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值