1 package org
.argeo
.cms
.security
;
3 import static javax
.xml
.bind
.DatatypeConverter
.printBase64Binary
;
5 import java
.io
.IOException
;
6 import java
.math
.BigInteger
;
7 import java
.nio
.MappedByteBuffer
;
8 import java
.nio
.channels
.FileChannel
;
9 import java
.nio
.file
.FileVisitResult
;
10 import java
.nio
.file
.Files
;
11 import java
.nio
.file
.Path
;
12 import java
.nio
.file
.Paths
;
13 import java
.nio
.file
.SimpleFileVisitor
;
14 import java
.nio
.file
.attribute
.BasicFileAttributes
;
15 import java
.security
.MessageDigest
;
16 import java
.util
.zip
.Checksum
;
18 import org
.argeo
.cms
.CmsException
;
20 /** Allows to fine tune how files are read. */
21 public class ChecksumFactory
{
22 private int regionSize
= 10 * 1024 * 1024;
24 public byte[] digest(Path path
, final String algo
) {
26 final MessageDigest md
= MessageDigest
.getInstance(algo
);
27 if (Files
.isDirectory(path
)) {
28 long begin
= System
.currentTimeMillis();
29 Files
.walkFileTree(path
, new SimpleFileVisitor
<Path
>() {
32 public FileVisitResult
visitFile(Path file
,
33 BasicFileAttributes attrs
) throws IOException
{
34 if (!Files
.isDirectory(file
)) {
35 byte[] digest
= digest(file
, algo
);
38 return FileVisitResult
.CONTINUE
;
42 byte[] digest
= md
.digest();
43 long duration
= System
.currentTimeMillis() - begin
;
44 System
.out
.println(printBase64Binary(digest
) + " " + path
45 + " (" + duration
/ 1000 + "s)");
48 long begin
= System
.nanoTime();
50 try (FileChannel channel
= (FileChannel
) Files
51 .newByteChannel(path
);) {
52 length
= channel
.size();
54 while (cursor
< length
) {
55 long effectiveSize
= Math
.min(regionSize
, length
57 MappedByteBuffer mb
= channel
.map(
58 FileChannel
.MapMode
.READ_ONLY
, cursor
,
61 byte[] buffer
= new byte[1024];
62 while (mb
.hasRemaining()){
69 // MessageDigest subMd =
70 // MessageDigest.getInstance(algo);
72 // byte[] subDigest = subMd.digest();
73 // System.out.println(" -> " + cursor);
74 // System.out.println(IOUtils.encodeHexString(subDigest));
75 // System.out.println(new BigInteger(1,
76 // subDigest).toString(16));
77 // System.out.println(new BigInteger(1, subDigest)
78 // .toString(Character.MAX_RADIX));
79 // System.out.println(printBase64Binary(subDigest));
81 cursor
= cursor
+ regionSize
;
83 byte[] digest
= md
.digest();
84 long duration
= System
.nanoTime() - begin
;
85 System
.out
.println(printBase64Binary(digest
) + " "
86 + path
.getFileName() + " (" + duration
/ 1000000
87 + "ms, " + (length
/ 1024) + "kB, "
88 + (length
/ (duration
/ 1000000)) * 1000
89 / (1024 * 1024) + " MB/s)");
93 } catch (Exception e
) {
94 throw new CmsException("Cannot digest " + path
, e
);
98 /** Whether the file should be mapped. */
99 protected boolean mapFile(FileChannel fileChannel
) throws IOException
{
100 long size
= fileChannel
.size();
101 if (size
> (regionSize
/ 10))
106 public long checksum(Path path
, Checksum crc
) {
107 final int bufferSize
= 2 * 1024 * 1024;
108 long begin
= System
.currentTimeMillis();
109 try (FileChannel channel
= (FileChannel
) Files
.newByteChannel(path
);) {
110 byte[] bytes
= new byte[bufferSize
];
111 long length
= channel
.size();
113 while (cursor
< length
) {
114 long effectiveSize
= Math
.min(regionSize
, length
- cursor
);
115 MappedByteBuffer mb
= channel
.map(
116 FileChannel
.MapMode
.READ_ONLY
, cursor
, effectiveSize
);
118 while (mb
.hasRemaining()) {
119 nGet
= Math
.min(mb
.remaining(), bufferSize
);
120 mb
.get(bytes
, 0, nGet
);
121 crc
.update(bytes
, 0, nGet
);
123 cursor
= cursor
+ regionSize
;
125 return crc
.getValue();
126 } catch (Exception e
) {
127 throw new CmsException("Cannot checksum " + path
, e
);
129 long duration
= System
.currentTimeMillis() - begin
;
130 System
.out
.println(duration
/ 1000 + "s");
134 public static void main(String
... args
) {
135 ChecksumFactory cf
= new ChecksumFactory();
137 // Paths.get("/home/mbaudier/apache-maven-3.2.3-bin.tar.gz");
139 if (args
.length
> 0) {
140 path
= Paths
.get(args
[0]);
143 .get("/home/mbaudier/Downloads/torrents/CentOS-7-x86_64-DVD-1503-01/"
144 + "CentOS-7-x86_64-DVD-1503-01.iso");
146 // long adler = cf.checksum(path, new Adler32());
147 // System.out.format("Adler=%d%n", adler);
148 // long crc = cf.checksum(path, new CRC32());
149 // System.out.format("CRC=%d%n", crc);
150 String algo
= "SHA1";
151 byte[] digest
= cf
.digest(path
, algo
);
152 System
.out
.println(algo
+ " " + printBase64Binary(digest
));
153 System
.out
.println(algo
+ " " + new BigInteger(1, digest
).toString(16));
154 // String sha1 = printBase64Binary(cf.digest(path, "SHA1"));
155 // System.out.format("SHA1=%s%n", sha1);