js图片隐写-藏在图片中的小视频

在前2篇文章《js图片隐写-找出图片中隐藏的漂亮小姐姐》《js图片隐写-图片中还能藏文章???》中我们介绍了如何利用最低有效位算法将图片和文本隐藏到图片中并实现了隐藏内容的解析提取算法,本文我们将介绍如何将一个视频通过数据拼接的方式隐藏到图片中甚至是任意文件隐藏到另外一个文件中。

一、文件隐藏的原理

操作系统在解析某个文件的时候,是逐步读取文件数据进行解析的,直到遇到EOF(end of file,文件结尾)为止,对于超出EOF的数据,操作系统就不会再进行解析了,我们可以在文件EOF后添加任意其他数据,该操作不会影响操作系统对该文件的正常读取。

比如jpg图片的EOFFFD9

我们可以在FFD9后加入任意的内容,比如“hidden text”,该操作并不会影响图片的读取和显示,只是会增加图片的大小。

二、文件隐藏的实现

在知道了操作系统如何解析文件后,我们可以利用文件的EOF将其他文件写入到当前文件的EOF标志后,即可实现文件的隐藏,但是在做文件隐藏的过程中,我们需要注意以下几点:

①、在对文件数据做合并后,后期我们需要对文件做解析获取隐藏的文件,这个时候我们就需要知道两个文件数据的分割点,当然我们可以通过文件的开始和结束标志来做处理,但是这样比较麻烦,这里我们选择自定义一个分割的标志来简化程序:

const sep = '-sep-';

②、在后期解析隐藏文件时,我们需要通过不同文件的特定标识才能知道隐藏的是什么类型的文件,如果我们要做的是一个通用的文件隐藏程序,则我们需要维护一个非常庞大的文件标识映射表,为了简化代码的复杂度我们选择在做文件隐藏时在分割标识的后面加上隐藏文件的后缀名,考虑到大部分文件的后缀名都在4位以内,我们将存储后缀名的位置大小定为4,不够4位的用空格“ ”填充在结尾,最后的形成的分隔标识如下:

const sep1 = '-sep-jpg ';
const sep2 = '-sep-xlsx';

实现代码如下:

const sep = '-sep-';
const maxExtLength = 4;

function combineFiles(mainFile, hideFile) {
    if (!mainFile) {
        return alert('请选择主文件!');
    }
    if (!hideFile) {
        return alert('请选择需要隐藏的文件!');
    }
    Promise.all([
        blobToArrayBuffer(mainFile),
        blobToArrayBuffer(hideFile),
    ]).then(([mainBuffer, hideBuffer]) => {
        const mainData = new Uint8Array(mainBuffer);
        const mainFileExt = mainFile.name.split('.').slice(-1)[0];
        const hideFileExt = hideFile.name.split('.').slice(-1)[0];
        const dataView = new DataView(mainBuffer);
        const hideData = new Uint8Array(hideBuffer);
        const sepData = new TextEncoder().encode(sep + hideFileExt.padEnd(maxExtLength, ' '));
        const targetData = new Uint8Array(mainData.length + sepData.length + hideData.length);
        targetData.set(mainData, 0);
        targetData.set(sepData, mainData.length);
        targetData.set(hideData, mainData.length + sepData.length);
        const blob = new Blob([targetData], { type: mimeMap[mainFileExt] });
        downloadBlob(blob, `combine.${mainFileExt}`);
    });
}

三、解析并提取隐藏的文件

对于文件的解析我们只需要根据上面定义的规则,提取隐藏文件的后缀名并将文件数据分割开,最后根据后缀名和分割得到的文件数据还原隐藏的文件。

实现代码如下:

function parseFile(file) {
    if (!file) {
        return alert('请选择需要解析的文件!');
    }
    blobToArrayBuffer(file)
        .then(buffer => {
            const data = new Uint8Array(buffer);
            const endIndex = getHiddenFileIndex(data);
            if (endIndex === -1) {
                return alert('该文件没有解析出隐藏文件!');
            }
            const extData = data.subarray(endIndex, endIndex + maxExtLength);
            const ext = data2str(extData);
            const subData = data.subarray(endIndex + maxExtLength);
            const blob = new Blob([subData], { type: mimeMap[ext] });
            downloadBlob(blob, `parsed.${ext}`);
        });
}

四、结语

在上面的实现中,我们可以做到任意常见文件的互相隐藏,但是也遗留了一些问题,比如多次隐藏的情况下,我们在做解析时可能会提取一些多余的内容,有兴趣的朋友可以尝试去优化一下这块儿,到此,我们关于图片隐写术的内容就结束了,希望对大家能够有所帮助。

在线demo:https://demo.deanhan.cn/hideVideo/

如需下载本文涉及的源码及素材包,请在关注本站公众号后回复:hidevideo

系列文章导航:

第1节: js图片隐写-找出图片中隐藏的漂亮小姐姐

第2节: js图片隐写-图片中还能藏文章???

第4节: 你不知道的信息隐藏术-零宽字符的应用

第5节: 隐写术应用-从图片还原画板

  • 支付宝二维码 支付宝
  • 微信二维码 微信

本文地址: /hide-file-in-another-file.html

版权声明: 本文为原创文章,版权归 逐梦个人博客 所有,欢迎分享本文,转载请保留出处!

相关文章