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!')
1158

被折叠的 条评论
为什么被折叠?



