]> git.argeo.org Git - lgpl/argeo-commons.git/blob - util/DigestUtils.java
Prepare next development cycle
[lgpl/argeo-commons.git] / util / DigestUtils.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.util;
17
18 import java.io.File;
19 import java.io.FileInputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.nio.ByteBuffer;
23 import java.nio.channels.FileChannel;
24 import java.security.MessageDigest;
25 import java.security.NoSuchAlgorithmException;
26
27 /** Utilities around cryptographic digests */
28 public class DigestUtils {
29 private static Boolean debug = true;
30 // TODO: make it writable
31 private final static Integer byteBufferCapacity = 100 * 1024;// 100 KB
32
33 public static String digest(String algorithm, byte[] bytes) {
34 try {
35 MessageDigest digest = MessageDigest.getInstance(algorithm);
36 digest.update(bytes);
37 byte[] checksum = digest.digest();
38 String res = encodeHexString(checksum);
39 return res;
40 } catch (Exception e) {
41 throw new UtilsException("Cannot digest with algorithm " + algorithm, e);
42 }
43 }
44
45 public static String digest(String algorithm, InputStream in) {
46 try {
47 MessageDigest digest = MessageDigest.getInstance(algorithm);
48 // ReadableByteChannel channel = Channels.newChannel(in);
49 // ByteBuffer bb = ByteBuffer.allocateDirect(byteBufferCapacity);
50 // while (channel.read(bb) > 0)
51 // digest.update(bb);
52 byte[] buffer = new byte[byteBufferCapacity];
53 int read = 0;
54 while ((read = in.read(buffer)) > 0) {
55 digest.update(buffer, 0, read);
56 }
57
58 byte[] checksum = digest.digest();
59 String res = encodeHexString(checksum);
60 return res;
61 } catch (Exception e) {
62 throw new UtilsException("Cannot digest with algorithm " + algorithm, e);
63 } finally {
64 StreamUtils.closeQuietly(in);
65 }
66 }
67
68 public static String digest(String algorithm, File file) {
69 FileInputStream fis = null;
70 FileChannel fc = null;
71 try {
72 fis = new FileInputStream(file);
73 fc = fis.getChannel();
74
75 // Get the file's size and then map it into memory
76 int sz = (int) fc.size();
77 ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
78 return digest(algorithm, bb);
79 } catch (IOException e) {
80 throw new UtilsException("Cannot digest " + file + " with algorithm " + algorithm, e);
81 } finally {
82 StreamUtils.closeQuietly(fis);
83 if (fc.isOpen())
84 try {
85 fc.close();
86 } catch (IOException e) {
87 // silent
88 }
89 }
90 }
91
92 protected static String digest(String algorithm, ByteBuffer bb) {
93 long begin = System.currentTimeMillis();
94 try {
95 MessageDigest digest = MessageDigest.getInstance(algorithm);
96 digest.update(bb);
97 byte[] checksum = digest.digest();
98 String res = encodeHexString(checksum);
99 long end = System.currentTimeMillis();
100 if (debug)
101 System.out.println((end - begin) + " ms / " + ((end - begin) / 1000) + " s");
102 return res;
103 } catch (NoSuchAlgorithmException e) {
104 throw new UtilsException("Cannot digest with algorithm " + algorithm, e);
105 }
106 }
107
108 public static void main(String[] args) {
109 File file;
110 if (args.length > 0)
111 file = new File(args[0]);
112 else {
113 System.err.println("Usage: <file> [<algorithm>]" + " (see http://java.sun.com/j2se/1.5.0/"
114 + "docs/guide/security/CryptoSpec.html#AppA)");
115 return;
116 }
117
118 if (args.length > 1) {
119 String algorithm = args[1];
120 System.out.println(digest(algorithm, file));
121 } else {
122 String algorithm = "MD5";
123 System.out.println(algorithm + ": " + digest(algorithm, file));
124 algorithm = "SHA";
125 System.out.println(algorithm + ": " + digest(algorithm, file));
126 algorithm = "SHA-256";
127 System.out.println(algorithm + ": " + digest(algorithm, file));
128 algorithm = "SHA-512";
129 System.out.println(algorithm + ": " + digest(algorithm, file));
130 }
131 }
132
133 final private static char[] hexArray = "0123456789ABCDEF".toCharArray();
134
135 /**
136 * From
137 * http://stackoverflow.com/questions/9655181/how-to-convert-a-byte-array-to
138 * -a-hex-string-in-java
139 */
140 private static String encodeHexString(byte[] bytes) {
141 char[] hexChars = new char[bytes.length * 2];
142 for (int j = 0; j < bytes.length; j++) {
143 int v = bytes[j] & 0xFF;
144 hexChars[j * 2] = hexArray[v >>> 4];
145 hexChars[j * 2 + 1] = hexArray[v & 0x0F];
146 }
147 return new String(hexChars);
148 }
149
150 }