精华内容
下载资源
问答
  • PNG图片中写入隐藏信息

    千次阅读 2018-09-16 21:23:00
       由于最近做项目,遇到一个功能需要做,是往PNG图片里面写入隐藏的数据,然后将图片通过微信的方式分享出去,这时候保存下来的图片,可以从里面读取出写入的隐藏数据。   首先,我们需要了解什么是PNG格式,...
        

       由于最近做项目,遇到一个功能需要做,是往PNG图片里面写入隐藏的数据,然后将图片通过微信的方式分享出去,这时候保存下来的图片,可以从里面读取出写入的隐藏数据。
      首先,我们需要了解什么是PNG格式,以及PNG格式的图片数据是如何存储的,我们能将我们的数据写入到什么地方。
    具体的PNG格式文件的详细信息介绍可以参考以下地址:
      png的故事:获取图片信息和像素内容 - WEB前端 - 伯乐在线
      PNG文件结构分析 ---Png解析 - DoubleLi - 博客园
      在文章中我们了解到,PNG格式的文件,除了开始的8个字节是固定的,后面的格式都是一个一个的数据块结构,也就是chunk。而每个chunk的结构又是固定的:4个字节的数据长度,4个字节的chunk类型,不定长度的数据内容,4个字节的CRC校验码。那么根据这个结构,我们就可以很简单的去解析PNG图片了。
      为什么上面会提到解析PNG图片,是因为我们知道具体的格式后,才能知道如何往里面写入数据,同时,也知道如何去解析我们写入后的数据。
      根据后一篇文章,我们可以发现在类型是tEXt的时候,可以存放一些我们需要的数据,那么我的目的就是为png增加一个tEXt的chunk,这样,既不影响图片的显示,也顺利将数据写入了png图片中。那么将这个块写入什么位置呢?其实我做了一个简单的处理,就是放入到IEND的chunk之前,因为IEND是png的结束标识,而有些文章会建议将数据存在IEND的数据块中,因为IEND的数据内容是空的,所以可以写入。其实这是不好的,因为IEND作为PNG结束chunk,是不可以变的,也就是说最后的12个字节是不允许修改的,不然系统就会提示这个PNG图片有问题。(ios系统会直接提示)
      上面知道了如何解析,也知道了要把数据写到什么chunk里,也明确了信息写入的地方,那么我们就着手开始往里面添加数据了。
      由于是在iOS上实现的,具体贴出来的代码是iOS中的。

        NSData *data = UIImagePNGRepresentation(image);
        NSMutableData *newData = [[NSMutableData alloc]init];
        NSUInteger start = 0;
        //1、获取文件格式,前8个字节
        [self readByte:data start:start length:8];
        //2、读取数据块
        BOOL isContinue = YES;
        start = 8;
        while (isContinue) {
            //先读取chunk的前四个字节,得到数据的长度
            Byte *chunkDataLength = [self readByte:data start:start length:4];
            long length = [self translateLong:chunkDataLength length:4];
            
            start += 4;
            //再读取4个字节,得到数据chunk的类型
            Byte *chunkTypeData = [self readByte:data start:start length:4];
            NSMutableString *typeStr = [NSMutableString new];
            for(int i = 0;i<4;i++){
                Byte n = *(chunkTypeData+i);
                [typeStr appendFormat:@"%c",n];
            }
            
    //        Byte *dataByte = [self readByte:data start:start+4 length:length];
    //        NSMutableData *crcData = [NSMutableData new];
    //        [crcData appendBytes:chunkTypeData length:4];
    //        [crcData appendBytes:dataByte length:length];
    //        NSUInteger crcddd = [crcData crc32];
    //        Byte *crcByte = [self readByte:data start:start+4+length length:4];
    //        NSLog(@"%@ 数据类型: 数据长度:%ld  ; 计算的校验位 :%x %x %x %x ; 读取的校验位:%x %x %x %x",typeStr,length,(int)((crcddd>>24)&0xff),(int)((crcddd>>16)&0x00ff),(int)((crcddd>>8)&0x0000ff),(int)(crcddd&0x000000ff),
    //              *(crcByte+0),*(crcByte+1),*(crcByte+2),*(crcByte+3));
    //
                if([@"IEND" isEqualToString:typeStr]){
                    //复制头数据
                    Byte *headerByte = [self readByte:data start:0 length:start-4];
                    [newData appendBytes:headerByte length:start-4];
                    
                    /****** start:添加要写入的数据 ******/
                    //计算要写入的数据长度
                    NSData *strData = [@"要写入的内容字符串" dataUsingEncoding:NSUTF8StringEncoding];
                    //1、写入数据长度
                    NSUInteger strLength = strData.length;
                    Byte *lengthDataByte = [self translateLongToByte:strLength length:4];
                    [newData appendBytes:lengthDataByte length:4];
                    free(lengthDataByte);
                    //2、写入数据块类型
                    NSData *typeData = [@"tEXt" dataUsingEncoding:NSUTF8StringEncoding];
                    Byte *byte = (Byte *)malloc(4);
                    [typeData getBytes:byte length:4];
                    [newData appendBytes:byte length:4];
                    //3、写入字符串数据
                    [newData appendData:strData];
                    //4、写入crc
                    NSMutableData *crcData = [NSMutableData new];
                    [crcData appendBytes:byte length:4];
                    [crcData appendData:strData];
                    NSUInteger crcddd = [crcData crc32];
                    
                    NSUInteger value = crcddd;
                    Byte *buffer = (Byte *)malloc(4);
                    for (int i = 0; i < 4; i++) {
                        *(buffer+3-i) = (Byte) (value & 0x000000ff);// 将最低位保存在最低位
                        value = value >> 8; // 向右移8位
                    }
                    [newData appendBytes:buffer length:4];
                    
                    /****** end:添加要写入的数据 ******/
    
                    //复制后面底部数据
                    Byte *saliByte = [self readByte:data start:start-4 length:(data.length-start+4)];
                    [newData appendBytes:saliByte length:(data.length-start+4)];
                    isContinue = NO;
                    break;
                }
                start+=(length + 8);
                free(chunkDataLength);
                free(chunkTypeData);
        }
    
    

    上面就是具体的读取文本和写入文本的地方。上面的处理其实是将数据进行复制,也就是复制一个数据,然后把数据写入到新的数据中,这样就相当于新创建了一张PNG图片,然后是写入数据的新图片。
      接下来补充几张图片。第一张是对于原始的图片数据,读取图片中的每个chunk的数据类型和长度,以及crc校验码:


    7820436-32973c6dffca0564.png
    屏幕快照 2018-09-19 上午11.18.26.png

      在上面的图片中,我们明显看到了整个png图片中的数据结构,以及对应的数据块。这张pNG图片的数据还是旧数据,不包含我们需要添加的文本信息。下面是添加了文本信息后的图片数据。


    7820436-a35d45a1aedd6636.png
    屏幕快照 2018-09-19 上午11.18.36.png

      当我们有新的图片数据后,我们如果调用系统的方法来讲NSData数据转化为图片,那么这时候会出现部分数据丢失,包括添加的tEXt数据,也就是说,这种情况,我们不建议使用系统的方法来转化图片,而是直接以流的方式写入文件。下面的截图,是使用了系统方式保存图片后新的PNG图片读取时的数据内容。


    7820436-0bb68d7d98404f98.png
    屏幕快照 2018-09-19 上午11.19.21.png
    7820436-3bccbfa9bdb3e348.png
    屏幕快照 2018-09-19 上午11.18.46.png

      通过对比,我们明显的发型,数据中的iDOT和tEXt数据丢失了,这是我们不希望看到的。

    有几个方法需要补充一下

    -(Byte *)readByte:(NSData *)data start:(NSUInteger)start length:(NSUInteger)length{
        long newLength = length;
        if(data.length < start+length){
            newLength = data.length-start;
        }
        Byte *buffer = (Byte *)malloc(newLength);
        [data getBytes:buffer range:NSMakeRange(start, newLength)];
        return buffer;
    }
    -(Byte *)translateLongToByte:(long)value length:(long)length{
        Byte *buffer = (Byte *)malloc(length);
        long number = value;
        for (int i = 0; i < length; i++) {
            *(buffer+length-1-i) = (Byte) (number & 0x0f);// 将最低位保存在最低位
            number = number >> 4; // 向右移8位
        }
        return buffer;
    }
    
    -(long)translateLong:(Byte *)byteData length:(int)length {
        long value = 0;
        for(int i = 0; i < length; i++){
            long valuei = *(byteData+i);
            value += (valuei << (8*(length-i-1)));
        }
        return value;
    }
    
    

    crc方法

    -(int32_t)crc32
    {
        uint32_t *table = malloc(sizeof(uint32_t) * 256);
        uint32_t crc = 0xffffffff;
        uint8_t *bytes = (uint8_t *)[self bytes];
        
        for (uint32_t i=0; i<256; i++) {
            table[i] = i;
            for (int j=0; j<8; j++) {
                if (table[i] & 1) {
                    table[i] = (table[i] >>= 1) ^ 0xedb88320;
                } else {
                    table[i] >>= 1;
                }
            }
        }
        
        for (int i=0; i<self.length; i++) {
            crc = (crc >> 8) ^ table[(crc & 0xff) ^ bytes[i]];
        }
        crc ^= 0xffffffff;
        
        free(table);
        return crc;
    }
    

    在上面处理中,我们一直保持着NSData的类型,而不能讲NSData直接通过IOS自有方法去存储图片,因为这样会将图片里写入的这部分数据删除掉,具体原因未知。所以后续的办法就是通过NSData将数据直接由微信分享出去(微信的版本会影响微信存储的图片类型),这样保存的图片就不会丢失数据。也可以直接将NSData数据写入本地文件,也可以保存数据。

    展开全文
  • 图片中隐藏信息——图片隐写术

    万次阅读 2018-11-22 14:05:18
    而对于单个r,g或b,其范围0~255之间,可由一个字节(8位表示)。因此,当改变最低位的值时,对于整个图片来说,其视觉效果通过肉眼看不出来的。比如一组颜色白色(255,255,255),变为(25...

    https://www.jianshu.com/p/72f0d0953ca4

    主要原理:

    图片是由一个个像素组成的。每个像素由一组(r,g,b)值表示(png格式图片,多一个alpha透明度值)。而对于单个r,g或b,其范围在0~255之间,可由一个字节(8位表示)。因此,当改变最低位的值时,对于整个图片来说,其视觉效果通过肉眼看不出来的。比如一组颜色白色(255,255,255),变为(254,255,255)时,是看不出来变化的。
    因此,可将一组待隐藏信息转换为二进制后,再将每个二进制码存储在图片的像素中。

    原图片.png

     

    隐藏有信息后的图片.png

    实现步骤

    加密

    • 获取原图片像素(list)
    • 使像素最低位变为偶数
    • 待隐藏信息转换为二进制,并且对于单字节字符,当位数不够8时,在最高位补0
    • 将二进制的待隐藏信息依次与图片中每个像素的r、g、b进行相加

    解密

    • 获取隐藏有信息的图片的像素(list)
    • 获取像素值的最低位(隐藏的信息存储位置)
    • 获取存储的信息的二进制值
    • 按每8位为一组,将上述二进制转换为十进制形式
    • 采用chr函数,将十进制转为字符并存储到字符串中

    源码

    # -*- coding: utf-8 -*-
    from PIL import Image
    import sys 
    
    reload(sys) 
    sys.setdefaultencoding('utf8') 
    
    """
    取得一个 PIL 图像并且更改所有值为偶数(使最低有效位为 0)
    """
    def makeImageEven(image):
        pixels = list(image.getdata())  # 得到一个这样的列表: [(r,g,b,t),(r,g,b,t)...]
        evenPixels = [(r>>1<<1,g>>1<<1,b>>1<<1,t>>1<<1) for [r,g,b,t] in pixels]  # 更改所有值为偶数(魔法般的移位)
        evenImage = Image.new(image.mode, image.size)  # 创建一个相同大小的图片副本
        evenImage.putdata(evenPixels)  # 把上面的像素放入到图片副本
        return evenImage
    
    """
    内置函数 bin() 的替代,返回固定长度的二进制字符串
    """
    def constLenBin(int):
        binary = "0"*(8-(len(bin(int))-2))+bin(int).replace('0b','')  # 去掉 bin() 返回的二进制字符串中的 '0b',并在左边补足 '0' 直到字符串长度为 8
        return binary
    
    """
    将字符串编码到图片中
    """
    def encodeDataInImage(image, data):
        evenImage = makeImageEven(image)  # 获得最低有效位为 0 的图片副本
        binary = ''.join(map(constLenBin,bytearray(data, 'utf-8'))) # 将需要被隐藏的字符串转换成二进制字符串
        if len(binary) > len(image.getdata()) * 4:  # 如果不可能编码全部数据, 抛出异常
            raise Exception("Error: Can't encode more than " + len(evenImage.getdata()) * 4 + " bits in this image. ")
        encodedPixels = [(r+int(binary[index*4+0]),g+int(binary[index*4+1]),b+int(binary[index*4+2]),t+int(binary[index*4+3])) if index*4 < len(binary) else (r,g,b,t) for index,(r,g,b,t) in enumerate(list(evenImage.getdata()))] # 将 binary 中的二进制字符串信息编码进像素里
        encodedImage = Image.new(evenImage.mode, evenImage.size)  # 创建新图片以存放编码后的像素
        encodedImage.putdata(encodedPixels)  # 添加编码后的数据
        return encodedImage
    
    """
    从二进制字符串转为 UTF-8 字符串
    """
    def binaryToString(binary):
        
        index = 0
        string = []
        fun = lambda x, i: x[0:8]
       
        while index + 1 < len(binary):        
            chartype = binary[index:].index('0') # 存放字符所占字节数,一个字节的字符会存为 0
            if chartype == 0:
                chartype = 1        
            length = chartype*8
            
            for i in range(chartype):            
                ascode = int(binary[index+i*8:index+i*8+8],2)
                string.append(chr(ascode))
            index += length        
                
        return ''.join(string)
    
    """
    解码隐藏数据
    """
    def decodeImage(image):
        pixels = list(image.getdata())  # 获得像素列表
        binary = ''.join([str(int(r>>1<<1!=r))+str(int(g>>1<<1!=g))+str(int(b>>1<<1!=b))+str(int(t>>1<<1!=t)) for (r,g,b,t) in pixels]) # 提取图片中所有最低有效位中的数据
        
        # 找到数据截止处的索引
        locationDoubleNull = binary.find('0000000000000000')
        endIndex = locationDoubleNull+(8-(locationDoubleNull % 8)) if locationDoubleNull%8 != 0 else locationDoubleNull
        data = binaryToString(binary[0:endIndex])
        return data
    
    #隐藏信息
    encodeDataInImage(Image.open("1.png"), 'hello,欢迎你们').save('encodeImage.png')
    #读取信息
    print decodeImage(Image.open("encodeImage.png")).encode("gbk")
    
    

    参考来源

    https://www.shiyanlou.com/courses/651

     

    展开全文
  • 图片隐藏信息

    千次阅读 2013-07-26 08:27:49
    图片隐藏信息的技术实现 分类: 信息安全2011-06-02 23:41 13070人阅读 评论(10) 收藏 举报 工具python加密fileoutput 目录(?)[+]  上一个帖子,介绍了“用图片传播翻墙工具”。今天,...

    用图片隐藏信息的技术实现

    分类: 信息安全 13070人阅读 评论(10) 收藏 举报

    目录(?)[+]

      上一个帖子,介绍了“用图片传播翻墙工具”。今天,来聊一下其中的技术原理。如果你对IT技术没啥兴趣,可以略过本文。

    ★图片隐藏信息的用途


      先来说说信息隐藏的目的。俺大致总结了一下,信息隐藏可以用于如下几种场合。

    ◇规避敏感词过滤


      所谓的"敏感词过滤",常翻墙的同学,应该都很熟悉了。用图片来隐藏信息,可以规避GFW的敏感词过滤。

    ◇规避肉眼审查


      俺在上一个帖子介绍的方法(把翻墙工具嵌入图片中),主要是为了躲开网站管理人员的人工审查。国内的很多网站,对于上传的图片,都会进行人工审查。如果能通过技术手段把信息隐藏在图片中,而图片本身又看不出什么异样,人工审核就看不出来。

    ◇传递加密信息


      最后,图片还可以用来隐藏加密的信息。关于加密的用途及重要性,俺在“文件加密的扫盲介绍”中,已经强调过加密性。用图片来隐藏加密信息,除了具有加密的效果,还具有很大的欺骗性——因为外人难以知道一张图片是否包含有加密信息。

    ★准备工作——先压缩


      下面,俺会介绍几种不同的隐藏方式。在动手之前,先说一下准备工作——把要隐藏得文件先用压缩工具(比如 7zip 或 WinRAR)压缩一下。
      压缩有如下几个好处:
    优点1
    如果你要隐藏的文件是文本格式或者 Office 格式,它内部的内容是明码的。如果里面包含敏感词,在通过网络传输时,会遭遇敏感词过滤。而压缩后的文件,原有的内容已经变得面目全非,可以规律敏感词过滤。
    优点2
    压缩之后,体积变小,有利于增加隐蔽性。因此,应尽量使用"最大压缩"的选项。
    优点3
    对于后面介绍的2种方法(尾部追加法、内容覆盖法),如果你隐藏的文件是压缩格式的,到时候提取信息会很简便——直接用压缩工具来解压,即可。

    ★尾部追加法


      先介绍最简单的一种方法。

    ◇技术原理


      顾名思义,"尾部追加法"就是把要隐藏的文件追加到图片尾部。这种方法不会破坏图片原有的任何数据,因此,图片看起来和原来一模一样。

    ◇隐藏信息的步骤


      隐藏的过程很简单,用 Windows 内置的文件拷贝命令,即可完成。假设你的图片文件叫 A.JPG,需要隐藏的压缩文件叫 B.ZIP,那你只需要执行如下命令,就可以把两个文件合并成一个新文件。
    copy /b A.JPG + B.zip C.JPG
      执行完如上命令,即可得到一个新的图片文件 C.JPG。这个图片文件的大小是前两者的总和。你可以用各种看图工具来打开 C.JPG,不会看到什么异常。

    ◇提取信息的步骤


      由于你追加的是压缩文件,提取的时候就简单了——只要用压缩工具打开 C.JPG,就可以直接看到压缩包里面的内容了。

    ◇优点


    1、
    制作简单,一条 copy 命令就可以搞定;如果隐藏的是压缩文件,提取的过程也很简单。
    2、
    用看图工具看生成的新文件,还是跟原来一样。
    3、
    隐藏的文件,大小不受限制。比如,你可以在一张100K的图片尾部,追加200K的隐藏数据。

    ◇缺点


    1、
    由于隐藏的文件附加在尾部。当你把这个新的图片文件上传到某些贴图的网站,(假如这个网站对图片格式的校验比较严格)它有可能会发现图片尾部有多余的数据,并且会把这个多余的数据丢弃掉。
    2、
    追加后,图片的文件尺寸变大了。如果你追加的文件太大,容易被发现破绽。
    比方说,一张640*480的 JPEG 图片,大小竟然有好几兆,对于有经验的IT技术人员,一下子就会觉得有猫腻。

    ★内容覆盖法


      说完尾部追加的办法,再来介绍内容覆盖的办法。

    ◇技术原理


      通常,图片文件都有包含2部分:文件头和数据区。而"内容覆盖法",就是把要隐藏的文件,直接覆盖到图片文件的数据区尾部。比方说,某图片有100K,其中文件头占1K,那么,数据区就是99K。也就是说,最多只能隐藏99K的文件。
      切记:覆盖的时候,千万不可破坏文件头。文件头一旦破坏,这个图片文件就不再是一个合法的图片文件了。
      使用这种方法,对图片文件的格式,是有讲究的——最好用 24位色的 BMP 格式。一来,BMP 格式本身比较简单,数据区随便覆盖,问题不大;二来,24位色的 BMP 相对其它的格式 BMP,文件尺寸更大,可以隐藏更多内容。

    ◇隐藏信息的步骤


      用这个招数来隐藏信息,稍微有点麻烦,需要借助一些小工具。对于这种简单的活计,俺通常用Python脚本来搞定。以下是俺写的一个简单 Python 脚本。你的电脑中如果有Python环境,可以直接拿这个脚本去用。
      事先声明:如下代码没有严格计算 BMP 的文件头尺寸,俺只是大致预留了 1024 字节,感觉应该够了。
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    import sys
    
    def embed(container_file, data_file, output_file) :
        container = open(container_file, "rb").read()
        data = open(data_file, "rb").read()
    
        if len(data)+1024 >= len(container) :
            print "Not enough space to save", data_file
        else :
            f = open(output_file, "wb")
            f.write(container[ : len(container)-len(data)])
            f.write(data)
            f.close()
    
    if "__main__" == __name__ :
        try :
            if len(sys.argv) == 4 :
                embed(sys.argv[1], sys.argv[2], sys.argv[3])
            else :
                print "Usage:"
                print sys.argv[0], "container data output"
        except Exception,err :
            print err
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
      上述Python的代码,很好懂,有编程基础的同学,10分钟之内就可以用自己熟悉的语言重写一个类似的。
      另外,没学过 Python 的同学,如果有兴趣,可以看看俺之前写的系列帖子——为什么俺推荐Python?

    ◇提取信息的步骤


      和前一种方法类似。如果你覆盖的是压缩文件,提取的时候,可以用压缩工具打开图片,就可以直接看到压缩包里面的内容了。

    ◇优点


    1、
    图片的文件尺寸没变。
    2、
    虽然隐藏文件覆盖到数据区,破环了原图像的内容。但是从格式上来讲,该图片文件的格式还是合法的。
    因此,你可以把这种图片上传到各种贴图的网站,技术上不会出问题。
    3、
    如果隐藏的是压缩文件,提取的过程很简单。

    ◇缺点


    1、
    由于隐藏的文件覆盖了数据区,因此,图片在显示的时候,会有一块区域变成灰蒙蒙的。
    2、
    隐藏文件的大小,有一定的限制——不能大于图片数据区的尺寸。
    3、
    对图片格式有一定要求。此处再啰嗦一下,建议用 24位色的 BMP 格式。

    ★隐写法


      最后,来介绍一种最复杂,但是也最隐蔽的方法——隐写术。

    ◇技术原理


      此方法会涉及较深奥的技术领域,俺也就知道个大概。通俗地说:如果把图片的某个像素的颜色,进行微小的调整,肉眼是看不出来的;因此,专门的软件,利用某些高深的算法,就可以在变化的像素中隐藏信息。
      有兴趣的同学,可以看"这里"的介绍;懂洋文的,还可以看更详细的介绍,在"这里"。

    ◇隐藏/提取信息的步骤


      使用这种方法,你需要用专门的工具来进行信息的隐藏和提取。在进行隐藏时,你除了指定图片文件和被隐藏的文件,还需要设置一个密码。隐写工具会把你的隐藏文件先加密,然后再进行隐写;提取的时候,需要用同一款隐写工具进行提取,并输入同样的密码,才能提取出来。
      假如图片文件落入攻击者手中,他必须同时知道2个信息(你用哪款隐写工具,你隐写时设置的密码),才有可能破解出隐含的信息。因此,安全性很高。

    ◇相关工具


      下面介绍几款工具,大伙儿可以根据自己喜好,挑选一个试试看。

    名称 官网 界面 类型
    Silent Eye 这里 图形界面 开源软件
    Steg Hide 这里 命令行界面 开源软件
    Ultima Steganography 这里 图形界面 商业软件


    ◇优点


    1、
    隐蔽性非常好。图片看上去几乎没变(其实是有极其轻微的变化,但是肉眼看不出)。并且,图片文件的大小也没变化。
    即使是专业人士,也很难判断一张图片是否包含了隐写术的数据。

    ◇缺点


    1、
    隐藏信息和提取信息比较麻烦,需要使用专门的工具。
    2、
    只能隐藏较少的信息。
    此方法能隐藏的信息量,和图片面积有关,和图片格式无关。比如一张1600*1200尺寸的,无论哪种格式,大约只能隐藏几KB的数据。

    ★结尾


      刚才介绍的几个招数,除了可以用于图片文件,也可以用在其它的多媒体文件中(比如:音频文件、视频文件)。有兴趣的网友,可以自个儿研究一下。

    俺博客上,和本文相关的帖子(需翻墙)
    用图片传播翻墙软件

    版权声明
    本博客所有的原创文章,作者皆保留版权。转载必须包含本声明,保持本文完整,并以超链接形式注明作者编程随想和本文原始地址:
    http://program-think.blogspot.com/2011/06/use-image-hide-information.html

    上一篇:TrueCrypt——文件加密的法宝下一篇:开源点评:ZeroMQ简介
    查看评论
    7楼 Jump2cn 2011-10-21 09:00发表 [回复]
    博主所说的隐写术更正式的称呼应该是“Data hiding in image”,刚好这学期我有上这门课。从名字上看,似乎还有很多隐藏方向。
    我们教的都是用灰度图片来做。灰度的图片数值都是0~255,也就是8个位,通过修改低位(LSB)来隐藏数据。其实博主所说的肉眼不可见不太准确 ,应该是肉眼不可识别隐藏信息,如前面所说,如果修改的位太多,像素的差异会很明显(失真)。基于这个理念衍生了很多算法,主要是藏入方法的改进,调整藏入后像素值的改进,嗯,应该还有其他方向(木有认真听课..)。
    不过Data hiding in image已经有方法(SPAM)可以检测出来,SPAM好像是使用数学统计的方法来侦测修改,对各种隐藏算法的侦测命中率非常高。通过SPAM数据进行libsvm训练得到的命中率基本都在90%~100%。藏入的数据量越多命中率越高。
    嗯,还学上这门课,就这么多吧。
    Re: program_think 2011-11-03 09:42发表 [回复]
    回复Worms1303:这位同学的评论很专业 :)
    6楼 blogdevteam 2011-07-28 16:15发表 [回复]
    尊敬的博客专家:
    您好!
    CSDN新版博客专家实行实名制原则,目前您还没有提供实名等信息,请您在2011年8月4日前在http://surveies.csdn.net/survey/comein/222填写您的实名等信息并提交,或将信息发送至:blog@csdn.net。谢谢~
    5楼 ruckfull 2011-06-29 23:46发表 [回复]
    我实验了copy的办法 为什么用压缩软件看不到隐藏的信息啊 球指点下 刚接触这个 有点白了[e07]
    4楼 laolaolihui 2011-06-22 09:23发表 [回复]
    感谢。学习了。。。
    3楼 kds622 2011-06-03 15:29发表 [回复]
    作为新人,表示很神奇
    2楼 littlehedgehog 2011-06-02 23:46发表 [回复]
    貌似 墙外不能评论啊
    Re: program_think 2011-06-03 00:04发表 [回复]
    可以评论,而且支持匿名评论。
    你大概因为翻墙碰到啥问题,所以无法评论吧。
    1楼 littlehedgehog 2011-06-02 23:46发表 [回复]
    比方说,某图片有100K,其中文件头占1K,那么,数据区就是99K。也就是说,最多只能隐藏9K的文件.
    第一反应是 100K - 1K = 9K? 不会吧 难道说有啥高深的算法?
    Re: program_think 2011-06-03 00:01发表 [回复]
    回复很迅速啊 :)
    俺少敲了一个“9”,已经更正。
    抱歉!
    展开全文
  • 图片隐藏信息

    千次阅读 2017-10-25 21:43:50
    图像如何隐藏信息我们知道,信息加密的方式多种多样。我要介绍的是用图像对信息进行加密。 你能相信上面这张图里可能隐藏着信息吗?首先,我们要了解图片的组成。一张图片,我们可以通过水平和竖直划分为许多小格...

    图像如何隐藏信息


    我们知道,信息加密的方式多种多样。我要介绍的是用图像对信息进行加密。
    此处输入图片的描述
    你能相信上面这张图里可能隐藏着信息吗?

    首先,我们要了解图片的组成。一张图片,我们可以通过水平和竖直划分为许多小格,称为像素点。而每一个像素点可以用1位(0,1)、4位(0-15)、8位(0-255)、24位二进制数表示。
    1位二进制只能表示0或1,即黑白两色。用4位表示则可以表示16种组合,如果把这16种组合看成颜色,就可以组成16色彩色的图像。用8位就有256种组合,可以由浅到深表达256级灰度。一幅图像可以看做像素点的个数乘以像素点的位数。现在的图像大多用24位表示即真彩色,其中8位表示红色,8位表示绿色,8位表示蓝色,即三原色。
    假设一副图像只有两种颜色,红与黑,拿出一列像素点:

    0 0 0 0 0 146 146 0 0

    显然一个146无法隐藏信息,那么我们将它化为二进制:10010010将其从最高位到最低位竖起来写:
    1 –高位
    0
    0
    1
    0
    0
    1
    0 –低位
    对于高位,把1改为0,则代表的十进制146则变成了18,差别非常大,如果反映到颜色上一眼就能看出。而至于低位,把0变为1,十进制变为147,对于颜色的改变微乎其微,肉眼很难分辨。所以,我们可以通过低位的变化隐藏一些信息。
    所以这列像素可以按高低位排列:

    000001100 —高位位平面
    000000000
    000001100
    000000000
    000000000
    000001100
    000000000 —低位位平面

    我们将利用低位位平面将信息隐藏进去。
    假设我要隐藏A这个字母,显然无法将A直接插进去。我们这时候可以将A也化为0-1序列。这就要用到ASCII码表。

    此处输入图片的描述
    其中,A可表示为01000001。接下来我们将把这个序列合并到低位位平面中。
    这就需要用到二进制的运算:与,或,异或等。比如:10001111 AND 11111110,结果为10001110。这就把最后一位化为了0。同理,如果想让哪一位变成0,就让11111111中对应位改为0后进行与运算。同样的,如果想把某一位改为1,则将00000000对应位置改为1后进行或运算即可。
    所以,操作过程即为:

    IF 待隐藏信息的第i位为0 then
    第i个像素的值=
    第i个像素的值 AND 11111110
    ELSE
    第i个像素的值=
    第i个像素的值 OR 00000001
    END IF

    这样,我们就把A隐藏在了图片中,而图片本身基本没有变化。所以,我们只要有原图和改变后的图就可以将信息翻译出来了。
    那么下次我们看到一幅图的时候,它后面是否隐藏着某些信息呢?

    展开全文
  • 如何在图片中隐藏数据

    千次阅读 2014-10-22 17:56:17
    这样,把两个文件拼接一起后,JPEG解压到“JPEG文件尾”(实际上是中间某处)就结束了,而RAR是直接搜索这个“RAR文件头”(也有可能是RAR的文件头文件最后?待确认),对这个指示的部分进行处理,而无视了前面...
  • 利用Python实现图片信息隐藏

    千次阅读 2018-04-25 20:33:06
    最近上了一门信息隐藏的课,讲的关于技术层面的内容还是蛮多的,但是我也没记住几个。吭吭,言归正传,这两天要交大作业,自己手动实现一种图像信息隐藏,查了一番资料后,决定Python来做(主要是调用包方便),原理...
  • 图片嵌入隐藏-大容量的信息隐藏算法

    万次阅读 热门讨论 2016-05-02 23:14:25
    今天分享一下最近看到的一个图片嵌入隐藏的算法。  这是一种基于空间域的...该算法的主要思想是对每个像素点进行判断,根据HVS的特性,最高非0有效位后的指定位(y)开始嵌入隐藏信息,嵌入到另一个指定位(z)为止。
  • 查找图片中隐藏的flag

    千次阅读 2019-09-27 05:33:05
    比如我们现有图123.jgp,要对它进行分析,查找图片中隐藏的flag,首先要了解一些关于图片格式的知识,这里举例jpg格式的图片,其他格式图片自行google一下。 jpg图片格式知识:  jpg格式文件开始的2字节是图像...
  • LSB一张图片隐藏信息

    千次阅读 2018-09-18 13:54:31
    CTF之隐写术--LSB一张图片隐藏信息 2017年04月09日 19:50:51 Unitue_逆流 阅读数:12492 标签: CTF 更多 个人分类: 网络安全 实验吧图片链接:http://ctf5.shiyanbar.com/stega/nvshen.jpg  使用工具...
  • 图片隐藏信息的技术实现

    千次阅读 2013-03-15 07:54:09
    图片隐藏信息的用途  先来说说信息隐藏的目的。俺大致总结了一下,信息隐藏可以用于如下几种场合。 (涉及敏感内容,此处省略191字) ◇传递加密信息  最后,图片还可以用来隐藏加密的信息。关于加密的用途...
  • cmd运行命令: ...如果b.txt是按照UTF-8编码的,则当用Notepad++等文本编辑工具打开新生成的c.jpg文件并采用UTF-8编码查看的时候,可以c.jpg文件的最后看到b.txt信息(UTF-8编码支持中文)。 如果b
  • 利用LSB算法隐藏图片信息的MATLAB实现

    万次阅读 多人点赞 2016-03-21 21:38:34
    前一篇博客介绍了利用LSB算法...此基础上,下面介绍利用LSB算法隐藏图片信息的MATLAB实现。补充说明 图片数据量较大,一个1920×10801920 \times 1080 的图片就有 6912000 个RGB值需要储存 依旧利用之前改进的算
  • LSB算法BMP图片信息隐藏技术 c语言

    千次阅读 2016-12-01 16:28:02
    LSB算法是将信息的每一位隐藏图片RGB单元的最后一位,由于一位的改变对于颜色影响不大,人的肉眼难以识别,从而达到信息隐藏的效果。 具体需要了解BMP文件格式,前54个字节为图片信息,不能修改,所以从第55个字节...
  • 经测试结果表明:通过该最低有效位(LSB)算法,能够实现一副比如(40×40,4.74KB)的24位位图隐藏600个字节的信息,并且,图片隐藏信息的能力与它自身的大小成正比。而通信双方只能输入正确密钥的情况下才能...
  • GIF图片中隐藏任意脚本的方法

    千次阅读 2015-05-19 18:25:51
    版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息 -= 写前面的,但不是废话 =- Update-1: 看到QQ围脖上大家的讨论,发现RSnake早07年就介绍过这个方法,看来是我out了。 ...
  • 呵呵,当然算法不是我的,是一次无意间看关于信息安全方面的书籍时,看到“最低有效位隐藏信息”这个名词。 于是网上查,论文比较多,但都要收费,偶尔有几篇前面的有一点信息。 于是就了下文: 其实讲了...
  • CTF之隐写术--LSB一张图片隐藏信息

    千次阅读 2018-11-13 18:33:46
    CTF之隐写术--LSB一张图片隐藏信息
  • Unity,我有一种图片,如何点击按钮让图片隐藏,再次点击显示,再点击隐藏...
  • 深度学习在信息隐藏中的应用(上)

    万次阅读 多人点赞 2017-11-07 17:24:51
    之前都是实验室做项目,写代码,没有系统集中的看过paper,最近要准备开题,集中看了十几篇,全是深度学习在信息隐藏领域的应用与研究。这里主要是对十几篇论文做一个总结,以后会不间断更新最新读的论文。 大家...
  • 如电影所讲,现实也有着类似的情节,我们的生活,我们所看过的图片、视频和游览过的网页,也许就隐藏着他人需要传输的秘密信息(是不是有点恐怖,差一点成为帮凶了),这就是信息隐藏!由于应用场景一般比较...
  • CTF中图片隐藏文件分离方法总结

    万次阅读 2017-06-06 12:15:24
    0x00 前言 安全的大趋势下,信息安全越来越来受到国家和企业的重视,所以CTF比赛场次...转到CTF比赛上,通常CTF比赛常有与隐写术(Steganography)相关的题目出现,这里我们讨论总结图片隐藏文件分离的方法
  • 图片隐藏数据的技术

    千次阅读 2017-06-14 22:07:07
    图片中隐藏数据是一件可繁可简的事情。 ★尾部追加法  先介绍最简单的一种方法。 ◇技术原理  顾名思义,"尾部追加法"就是把要隐藏的文件追加到图片尾部。这种方法不会破坏图片原有的任何数据,因此...
  • 信息隐藏——二值图像的信息隐藏

    千次阅读 2020-06-24 21:28:42
    二值图像的信息隐藏 ...用MATLAB函数实现二值图像隐藏信息的提取 ■三.分析阈值R0,R1 以及健壮参数λ对实验结果的影响 一.用MATLAB函数实现二值图像信息隐藏 1.读取(预处理后的)目标图片与要隐藏的信
  • (有趣)把文字隐藏图片中

    千次阅读 2016-04-27 23:26:11
    你可以下载此图片将文件格式由jpg转换为txt,用记事本打开即可,就会看到最后一行你加入的信息 建立一个文本文件(.txt),把要写的内容写到里面。注意,前面要空一两行,不能起头就写东西,否则第一行的内容会...
  • 将文件内容隐藏到png图片中

    千次阅读 2015-11-19 15:27:17
    要想更好的实现该功能,你可以阅读将文件内容隐藏到bmp图片中 要实现这个功能,你得了解png文件的格式,详情:http://www.w3.org/TR/PNG/ 实现原理: png文件格式包括固定的文件头部+ 必要的数据块和辅助数据块 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 165,503
精华内容 66,201
关键字:

如何在图片中隐藏信息