png文件分析

png文件分析

这是一个生成2*2=4个像素的简单png文件的代码。

本文实现了一个简单png文件的生成,
及其iDat数据的加密和解密过程。

加密用java语言,解密用python语言。

解密是zip的解密,用到python的zip库。

这4个像素是: //png的IDAT数据部分
byte[] rgbData=new byte[]{00, (byte) 0xff,00,00,00,00, (byte) 0xff,00,00,00, (byte) 0xff, (byte) 0xff,00,00};


00 FF 00 00 00 00 FF 
00 00 00 FF FF 00 00

其中,第一列是00,第二列到第四列是r g b,rgb(255,0,0)是一个红点,
第五列到第七列是r g b,rgb(0,0,255)是一个蓝点。
第二行,第一列是00,每行开头都是00, 接着是一个蓝点,一个红点。

以下是png生成后的iDat数据:

 把iDat导出到a3.bin文件,用以下python 程序解密成以下数据。

 这就是png中rgb的数据。

 Java代码:png生成加密过程

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mycompany.a1;

import java.io.*;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.zip.CRC32;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
;

/**
 *
 * @author Administrator
 */
public class NewClass {
    public static int id;
    
    public static void main(String[] args) throws IOException {
        writePng();
        System.out.println("文件创建成功!");
    }
    private static void writePng() throws IOException {
        File file = new File("G:\\g\\sys4\\game3\\t1\\pngcheck-3.0.3-win32\\a.png");
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        //写png头部
        fileOutputStream.write(new byte[]{(byte) 0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a});
        //png的IHAD数据块
        fileOutputStream.write(pngChunkData(new byte[]{0x49,0x48,0x44,0x52},new byte[]{00,00,00,02,00,00,00,02,0x08,02,00,00,00}));
        //png的IDAT数据部分
        byte[] rgbData=new byte[]{00, (byte) 0xff,00,00,00,00, (byte) 0xff,00,00,00, (byte) 0xff, (byte) 0xff,00,00};
        fileOutputStream.write(pngChunkData(new byte[]{0x49,0x44,0x41,0x54},deflateZip(rgbData)));
        //写png尾部
        fileOutputStream.write(pngChunkData(new byte[]{0x49,0x45,0x4e, (byte) 0x44},null));
        fileOutputStream.close();
        System.out.println("操作成功");
    }
    /**
     * deflateZip压缩
     * @param source
     * @return
     */
    private static byte[] deflateZip(byte[] source) throws IOException{
        String vv="G:\\g\\sys4\\game3\\t1\\3\\a1.txt";
        BufferedWriter out = new BufferedWriter(new FileWriter(vv));
        
        String vvv= "G:\\g\\sys4\\game3\\t1\\3\\a2.txt";
        File f = new File(vvv);
        OutputStream fOut = new FileOutputStream(f);
        
        Deflater deflater = new Deflater();
        deflater.setInput(source);
        deflater.finish();
        byte[] tem=new byte[64];
        byte[] dataByte=new byte[0];
        int deflate=0;
        while (!deflater.finished()){
             deflate = deflater.deflate(tem);
            // out.write(deflate);
             //fOut.write(deflate);
            byte[] array = ByteBuffer.allocate(deflate).put(tem, 0, deflate).array();
            byte[] temByte=new byte[dataByte.length+array.length];
            System.arraycopy(dataByte,0 , temByte, 0,dataByte.length );
            System.arraycopy(array, 0, temByte, dataByte.length, array.length);
            dataByte=temByte;
           
        }
        int len=dataByte.length;
        String txt;
        for(int i=0;i<len;i++)
        {
           int b=dataByte[i];
           //txt=dataByte[i];
            System.out.println(Integer.toHexString(b));
           out.write(Integer.toHexString(b)+"\n\r");
           fOut.write(b);
        
        }
        deflater.end();

            out.close();
            fOut.close();
        return dataByte;
    }

    /**
     * 数据块数据
     * @return
     */
    private static byte[] pngChunkData(byte[] chunkType,byte[] data) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int dataLength=0;
        byte[] crcCheckSource= Arrays.copyOf(chunkType,chunkType.length);
        if(data!=null){
            dataLength=data.length;
            baos.write(crcCheckSource);
            baos.write(data);
            crcCheckSource=baos.toByteArray();
            baos.reset();
        }
        byte[] crcCheck = crc32CheckValue(crcCheckSource);
        baos.write(ByteBuffer.allocate(4).putInt(dataLength).array());
        baos.write(chunkType);
        if(data!=null){
            baos.write(data);
        }
       baos.write(crcCheck);
        return baos.toByteArray();
    }

    /**
     * 计算CRC32校验值
     * 参考:http://www.libpng.org/pub/png/spec/1.0/PNG-Structure.html#CRC-algorithm
     * crc32的二项目市为(w3c规定):CRC32=X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X1+X0
     * ng中的crc32原理: 与标准crc32有所不同,对数据处理前后各做了一些处理(初始余数寄存器为全一,最终余数取反(据w3c标准规定))
     * 原二项式:1 00000100 11000001 00011101 10110111
     * 去除最高位:100110000010001110110110111 =0X04C1BDD7L
     * 首位倒置:  111011011011100010000011001=0xEDB88320L;
     * @return
     */
    private static byte[] crc32CheckValue(byte[] bytes) {
        CRC32 crc32 = new CRC32();
        crc32.update(bytes);
        int value = (int) crc32.getValue();
        return ByteBuffer.allocate(4).putInt(value).array();
    }


}

python代码:解密过程

  

import zlib
 
 
# 压缩文件或数据
def compress_data(file, zip_file, level=9):
    file = open(file, 'rb')
    zip_file = open(zip_file, 'wb')
    compress = zlib.compressobj(level)
    data = file.read(1024)
    while data:
        zip_file.write(compress.compress(data))
        data = file.read(1024)
    zip_file.write(compress.flush())
    file.close()
    zip_file.close()
 
 
# 解压文件或数据
def decompress_data(zip_file, new_file):
    zip_file = open(zip_file, 'rb')
    new_file = open(new_file, 'wb')
    decompress = zlib.decompressobj()
    data = zip_file.read(1024)
    while data:
        new_file.write(decompress.decompress(data))
        data = zip_file.read(1024)
    new_file.write(decompress.flush())
    zip_file.close()
    new_file.close()
 
 
if __name__ == '__main__':
    #file = 'text.txt'
    #zip_file = 'text_zip.txt'
    #compress_data(file, zip_file)
	
    zip_file="a3.bin"
    new_file ='a3_out.bin'
    decompress_data(zip_file, new_file)
    print('end!')
	
	
	
	
	
	
	
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值