十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
转个过来,每种类型的文件前几个字节固定,可以根据头部几个字节判断文件格式
为乐山等地区用户提供了全套网页设计制作服务,及乐山网站建设行业解决方案。主营业务为成都网站设计、成都网站建设、乐山网站设计,以传统方式定制建设网站,并提供域名空间备案等一条龙服务,秉承以专业、用心的态度为用户提供真诚的服务。我们深信只要达到每一位用户的要求,就会得到认可,从而选择与我们长期合作。这样,我们也可以走得更远!
图片的格式很多,一个图片文件的后缀名并不能说明这个图片的真正格式什么,那么如何获取图片的格式呢?我想到了几个简单但有效的方法,那就是读取图片文件的文件头标识。我们知道各种格式的图片的文件头标识识不同的,因此我们可以通过判断文件头的标识来识别图片格式。
我对各种格式的图片文件头标识进行了分析,不仅查找资料,也用十六进制编辑器察看过图片的文件头,以下是我收集、分析的结果,供大家参考。
1.JPEG/JPG
-
文件头标识 (2 bytes): $ff, $d8 (SOI) (JPEG 文件标识)
- 文件结束标识 (2 bytes): $ff, $d9
(EOI)
2.TGA
- 未压缩的前5字节 00 00 02 00 00
- RLE压缩的前5字节 00 00
10 00
00
3.PNG
- 文件头标识 (8 bytes) 89 50 4E 47 0D 0A 1A
0A
4.GIF
-
文件头标识 (6 bytes) 47 49 46 38 39(37)
61
G I F 8 9
(7) a
5.BMP
- 文件头标识
(2 bytes) 42 4D
B
M
6.PCX
- 文件头标识 (1
bytes) 0A
7.TIFF
- 文件头标识 (2 bytes)
4D 4D 或 49
49
8.ICO
- 文件头标识 (8 bytes) 00 00 01 00 01 00 20 20
9.CUR
- 文件头标识 (8 bytes) 00 00 02 00 01 00 20
20
10.IFF
-
文件头标识 (4 bytes) 46 4F 52
4D
F O R M
11.ANI
- 文件头标识 (4 bytes)
52 49 46
46
R I F F
根据这些文件头标识的收集,我可以写一个识别图像格式的模块了。但是在写这个模块之前可以对收集到的文件头标识进行优化,使得程序中字符串比对次数尽量的少。
1.JPEG我们知需要比对文件头的$ff,
$d8这两个字符,而不用读取最后的两个结束标识了。
2.TGA,ICO,CUR只需比对第三个与第五个字符即可。
3.PNG比对[89][50]这两个字符。
4.GIF比对[47][49][46]与第五个字符。
废话不多说了,利用内存流来判断文件的格式,其实判断文件的前几个字节就可以简单的判断这个文件是什么类型的文件,例如
jpg文件
是 FFD8 (从低位到高位就要反过来 D8FF 下面都是一样)
BMP文件 是 424D
---4D42
其他的我就不一一列举了,想知道跟多文件类型分别是用什么字符作为文件的开头的话,下载个C32asm或者UE等这类16进制编辑器就可以看到了。
从JAVA打基础到安卓没问题,但是修改源码就不一定能达到你想要的效果了,首先很多软件加密,你不一定能反编译出源码(需要你有反编译的能力)。其次,很多软件也不一定是用JAVA或Android编写的。windows平台上的很多软件都是用vb、vc、c#、.net编写的。
计算MD5或SHA-1,一样的就是同一个文件
下面的代码,不需要额外使用第三方组件,且支持超大文件
// 计算文件的 MD5 值
publicstatic String getFileMD5(File file) {
if (!file.isFile()) {
return null;
}
MessageDigest digest = null;
FileInputStream in = null;
byte buffer[] = newbyte[8192];
int len;
try {
digest =MessageDigest.getInstance("MD5");
in = new FileInputStream(file);
while ((len = in.read(buffer)) != -1) {
digest.update(buffer, 0, len);
}
BigInteger bigInt = new BigInteger(1, digest.digest());
return bigInt.toString(16);
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 计算文件的 SHA-1 值
publicstatic String getFileSha1(File file) {
if (!file.isFile()) {
return null;
}
MessageDigest digest = null;
FileInputStream in = null;
byte buffer[] = newbyte[8192];
int len;
try {
digest =MessageDigest.getInstance("SHA-1");
in = new FileInputStream(file);
while ((len = in.read(buffer)) != -1) {
digest.update(buffer, 0, len);
}
BigInteger bigInt = new BigInteger(1, digest.digest());
return bigInt.toString(16);
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Xmonitor会维护一个本地代码仓库,被启动时将检查线上代码库与本地维护的代码(历史版本)是否一样,如果发生变更则去找出变更了的方法,并判定这些变更的方法是否被测试CASE(service的单测CASE)覆盖到。当然也可以用它找出当前版本中所有的没有被case覆盖到的生产方法和已经被覆盖到的生产方法。
从开发的模块上分为五个部分,获取CASE依赖、获取最新版本代码、抽取测试覆盖方法、抽取生产代码方法、获取测试覆盖/未覆盖,见下图:
目录结构说明:
1.bin目录下存放sh文件:
getDiffRes.sh:调度java文件比对模块,完成工程下所有java文件方法抽取,并根据旧版本代码内容生成变更方法List.
createDependencyXML.sh:调度第三方工具[dependencyFinder]捕获测试CASE覆盖到的生产方法。
compareJavaCode.sh :调度代码比对模块是生成最新的代码变更生产代码中的方法。
2.lib目录下存放jar包,用于java程序执行:
CompareJavaCode.jar:完成新旧版本java文件对比,生成变更方法记录、接口-实现类关系。
CreateXmonitorXML.jar:生成xml格式的最终结果{此次变更中未覆盖的生产方法、此次变更中已覆盖的方法、所有代码中未覆盖的方法、所有代码中已覆盖的方法}。
GenNoCovModifyMethod.jar:引入测试CASE依赖信息、变更方法、接口-实现类关系,进行逻辑运算,生成各种情况下的覆盖/未覆盖生产方法列表。
3.conf目录下存放配置:di2ACC.conf、blacklist.dat
di2ACC.conf:工具依赖配置。
blacklistofnocover.dat、blacklistofcovered.dat:测试未覆盖、已覆盖过滤条件,对最后产出结果进行过滤。
注:默认过滤action包、bo包下的set、get方法,可以通过修改文件内容调整过滤条件。
3.Utils:工具函数目录,存放文件:Empty.java,getNoDuplicat.sh
getNoDuplicat.sh:结合blacklist.dat文件进行结果过滤。
Empty.java:一个空的java文件,协助生成java代码对比变更。
4.Data目录:程序运行中产出的各种结果文件。
5.Logs目录:用于存放日志,目前未开发独立的日志功能,试用期间以重定向的方式写Log.
6.main.sh:xmonitor工作主程序,完成对其他工作模块调度。