CheckPNGByCRC32

Run Settings
LanguageJava
Language Version
Run Command
import java.io.FileInputStream; import java.io.IOException; public class CheckPNGByCRC32 { static final int CHUNKTYPECODE_BYTE_LENGTH = 4; static int CHUNKDATA_BYTE_LENGTH = 0; static final int FILE_HEADER_BYTE_LENGTH = 8; static final int CRC_BYTE_LENGTH = 4; /** * byte数组转换成16进制字符串 * * @param src * @return */ public static String bytesToHexString(byte[] src) { StringBuilder stringBuilder = new StringBuilder(); if (src == null || src.length <= 0) { return null; } for (int i = 0; i < src.length; i++) { int v = src[i] & 0xFF; String hv = Integer.toHexString(v); if (hv.length() < 2) { stringBuilder.append(0); } stringBuilder.append(hv); } return stringBuilder.toString(); } /** * 根据文件流读取图片文件真实类型 // [-119, 80, 78, 71, 13, 10, 26, 10//文件头标识 * * @param is * @return */ public static String getTypeByStream(FileInputStream is) { byte[] b = new byte[FILE_HEADER_BYTE_LENGTH]; b = readInfoByLocation(FILE_HEADER_BYTE_LENGTH, is); String type = bytesToHexString(b).toUpperCase(); if (type.contains("FFD8FF")) { return "jpg"; } else if (type.contains("89504E47")) { return "png"; } else if (type.contains("47494638")) { return "gif"; } else if (type.contains("49492A00")) { return "tif"; } else if (type.contains("424D")) { return "bmp"; } return type; } public static byte[] readInfoByLocation(int length, FileInputStream is) { byte[] b = new byte[length]; try { is.read(b, 0, length); } catch (IOException e) { e.printStackTrace(); } return b; } /** * 解析IHDR数据块 * * @param is * @return */ public static String getIHDRInfo(FileInputStream is) { String fileType = "";// 文件标示 int IHDRLength = 0;// IHDR字节长度 String result = "";// 判断文件中CRC的值与根据数据块计算后的CRC是否相等,监测当前数据块是否被修改 byte[] b = new byte[CHUNKTYPECODE_BYTE_LENGTH]; b = readInfoByLocation(b.length, is); // 0, 0, 0, 13, //IHDR长度 IHDRLength = Integer.parseInt(bytesToHexString(b), 16); System.out.println("chunk data length:" + IHDRLength); byte[] ihdrData = new byte[IHDRLength + CHUNKTYPECODE_BYTE_LENGTH]; try { is.read(ihdrData); } catch (IOException e1) { e1.printStackTrace(); } // IHDR标示,16进制转换成ascII码再转成string为IHDR // 73, 72, 68, 82, //I H D R for (int i = 0; i < 4; i++) { fileType += String.valueOf(backchar(ihdrData[i])); } // IEND文件结束 System.out.println("Data block identification:" + fileType); // 0, 0, 3, 78,//宽 byte[] picWidthByte = { ihdrData[4], ihdrData[5], ihdrData[6], ihdrData[7] }; int picWidth = Integer.parseInt(bytesToHexString(picWidthByte), 16); System.out.println("picture width:" + picWidth); // 0, 0, 4, 127, //高 byte[] picHeightByte = { ihdrData[8], ihdrData[9], ihdrData[10], ihdrData[11] }; int picHeight = Integer.parseInt(bytesToHexString(picHeightByte), 16); System.out.println("picture heigh:" + picHeight); // 8, 色深 2的8次方=256 ,256真彩色 System.out.println("Color depth:" + new java.math.BigInteger("2").pow(ihdrData[12])); // 4 System.out.println("Color type:" + ihdrData[13]); // 00 PNG Spec规定此处总为0(非0值为将来使用更好的压缩方法预留),表示使压缩方法(LZ77派生算法) String compressionMethod = String.valueOf(ihdrData[14]); // 00 同上 String compressionMethod1 = String.valueOf(ihdrData[15]); // 00 非隔行扫描 String nonInterlacedScanning = String.valueOf(ihdrData[16]); // 读取文件中CRC值 byte[] crcInFileByte = new byte[CRC_BYTE_LENGTH]; crcInFileByte = readInfoByLocation(b.length, is); String crcInFileString = bytesToHexString(crcInFileByte).toUpperCase(); System.out.println("crc in file:" + crcInFileString); // 根据数据计算CRC String calcCrcByData = CrcTest.getCrc(ihdrData).toUpperCase(); System.out.println("calculate by data :" + calcCrcByData); if (crcInFileString.equals(calcCrcByData)) { result = fileType + "CRC right, not modify"; } else { result = fileType + "CRC wrong,modified"; } return result; } public static void readFile(FileInputStream is) { boolean isContinue=true; do{ String result = "";// 判断文件中CRC的值与根据数据块计算后的CRC是否相等,监测当前数据块是否被修改 String dataType = ""; byte[] b = new byte[CHUNKTYPECODE_BYTE_LENGTH]; b = readInfoByLocation(b.length, is); // 0, 0, 0, 13, //IHDR长度 int dataLength = Integer.parseInt(bytesToHexString(b), 16); System.out.println("chunk data length:" + dataLength); byte[] ihdrData = new byte[dataLength + CHUNKTYPECODE_BYTE_LENGTH]; try { is.read(ihdrData); } catch (IOException e1) { e1.printStackTrace(); } for (int i = 0; i < 4; i++) { dataType += String.valueOf(backchar(ihdrData[i])); } System.out.println("Data block identification:" + dataType); if(dataType.equals("IEND")){ isContinue=false; } // 读取文件中CRC值 byte[] crcInFileByte = new byte[CRC_BYTE_LENGTH]; crcInFileByte = readInfoByLocation(b.length, is); String crcInFileString = bytesToHexString(crcInFileByte).toUpperCase(); System.out.println("crc in file:" + crcInFileString); // 根据数据计算CRC String calcCrcByData = CrcTest.getCrc(ihdrData).toUpperCase(); System.out.println("calculate by data :" + calcCrcByData); if (crcInFileString.equals(calcCrcByData)) { result = dataType + " CRC right, not modify"; } else { result = dataType + " CRC wrong,modified"; } System.out.println(result); System.out.println(" ***** "); }while(isContinue); } /** * 字符转ASC * * @param st * @return */ public static int getAsc(String st) { byte[] gc = st.getBytes(); int ascNum = (int) gc[0]; return ascNum; } /** * ASC转字符 * * @param backnum * @return */ public static char backchar(int backnum) { char strChar = (char) backnum; return strChar; } public static String convertHexToString(String hex) { StringBuilder sb = new StringBuilder(); StringBuilder temp = new StringBuilder(); // 49204c6f7665204a617661 split into two characters 49, 20, 4c... for (int i = 0; i < hex.length() - 1; i += 2) { // grab the hex in pairs String output = hex.substring(i, (i + 2)); // convert hex to decimal int decimal = Integer.parseInt(output, 16); // convert the decimal to character sb.append((char) decimal); temp.append(decimal); } return sb.toString(); } public static byte[] hexStringToBytes(String hexString) { if (hexString == null || hexString.equals("")) { return null; } hexString = hexString.toUpperCase(); int length = hexString.length() / 2; char[] hexChars = hexString.toCharArray(); byte[] d = new byte[length]; for (int i = 0; i < length; i++) { int pos = i * 2; d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); } return d; } private static byte charToByte(char c) { return (byte) "0123456789ABCDEF".indexOf(c); } /* * JPEG (jpg),文件头:FFD8FF PNG (png),文件头:89504E47 GIF (gif),文件头:47494638 TIFF * (tif),文件头:49492A00 Windows Bitmap (bmp),文件头:424D */ public static void main(String[] args) throws Exception { String src = "D:\\maizi2.png"; FileInputStream is = new FileInputStream(src); String type = getTypeByStream(is); System.out.println("file type:" + type); System.out.println(" ***** "); String IHDR = getIHDRInfo(is); System.out.println("IHDR:" + IHDR); System.out.println(" ***** "); readFile(is); } }
Editor Settings
Theme
Key bindings
Full width
Lines