/**
* PODD is an OWL ontology database used for scientific project management
*
* Copyright (C) 2009-2013 The University Of Queensland
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU Affero General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/
package com.github.podd.utils;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.github.ansell.jdefaultdict.JDefaultDict;
public class PoddDigestUtils
{
/**
* An enumeration linking the MessageDigest algorithm identifier to the file extension used to
* store it.
*
* @author Peter Ansell p_ansell@yahoo.com
*/
public static enum Algorithm
{
SHA1("SHA-1", ".sha1"),
MD5("MD5", ".md5");
private final String name;
private final String extension;
Algorithm(final String name, final String extension)
{
this.name = name;
this.extension = extension;
}
public String getExtension()
{
return this.extension;
}
public String getName()
{
return this.name;
}
}
public static ConcurrentMap<Path, ConcurrentMap<Algorithm, String>> getDigests(final Collection<Path> pathsToDigest)
throws IOException, NoSuchAlgorithmException
{
final ConcurrentMap<Path, ConcurrentMap<Algorithm, String>> result =
new JDefaultDict<>(k -> new ConcurrentHashMap<>());
for(final Path nextPath : pathsToDigest)
{
try (final InputStream inputStream = Files.newInputStream(nextPath))
{
final DigestInputStream shaStream =
new DigestInputStream(inputStream, MessageDigest.getInstance(Algorithm.SHA1.getName()));
final DigestInputStream md5Stream =
new DigestInputStream(shaStream, MessageDigest.getInstance(Algorithm.MD5.getName()));
int b;
while((b = md5Stream.read()) != -1)
{
// No processing needed
}
final ConcurrentMap<Algorithm, String> nextMap = result.get(nextPath);
nextMap.computeIfAbsent(Algorithm.MD5, k -> {
final byte[] md5Digest = md5Stream.getMessageDigest().digest();
return new BigInteger(1, md5Digest).toString(16);
});
nextMap.computeIfAbsent(Algorithm.SHA1, k -> {
final byte[] shaDigest = shaStream.getMessageDigest().digest();
return new BigInteger(1, shaDigest).toString(16);
});
}
}
return result;
}
}