com.emc.esu.api.Checksum Maven / Gradle / Ivy
/*
* Copyright 2013 EMC Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.emc.esu.api;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import org.apache.log4j.Logger;
import org.concord.security.ccjce.cryptix.jce.provider.CryptixCrypto;
/**
* The checksum class is used to store and compute partial checksums when uploading
* files.
*/
public class Checksum {
private static final Logger l4j = Logger.getLogger( Checksum.class );
// Register SHA-0 provider
static {
Security.addProvider( new CryptixCrypto() );
}
/**
* The hash algorithm to use. As of 1.4.0, only SHA0 is supported
*/
public static enum Algorithm { SHA0, SHA1, MD5 };
private MessageDigest digest;
private Algorithm alg;
private long offset;
private String expectedValue;
public Checksum( Algorithm alg ) throws NoSuchAlgorithmException {
switch( alg ) {
case SHA0:
digest = MessageDigest.getInstance( "SHA-0" );
break;
case SHA1:
digest = MessageDigest.getInstance( "SHA-1" );
break;
case MD5:
digest = MessageDigest.getInstance( "MD5" );
break;
}
this.alg = alg;
offset = 0;
}
public String getAlgorithmName() {
switch( alg ) {
case SHA0:
return "SHA0";
case SHA1:
return "SHA1";
case MD5:
return "MD5";
}
throw new RuntimeException( "Unknown algorithm: " + alg );
}
/**
* Updates the checksum with the given buffer's contents
* @param buffer data to update
* @param offset start in buffer
* @param length number of bytes to use from buffer starting at offset
*/
public void update( byte[] buffer, int offset, int length ) {
digest.update(buffer, offset, length);
this.offset += length;
}
/**
* Outputs the current digest checksum in a format
* suitable for including in Atmos create/update calls.
*/
@Override
public String toString() {
String checksumData = getAlgorithmName()+"/"+offset+"/"+getHashValue();
l4j.debug( "Checksum Value: '" + checksumData + "'" );
return checksumData;
}
private String getHashValue() {
// Clone the digest so we can pad current value for output
MessageDigest tmpDigest;
try {
tmpDigest = (MessageDigest) digest.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException( "Clone failed", e );
}
byte[] currDigest = tmpDigest.digest();
// convert to hex string
BigInteger bigInt = new BigInteger(1, currDigest);
return String.format( "%0" + (currDigest.length << 1) + "x", bigInt );
}
/**
* Sets the expected value for this checksum. Only used for read operations
* @param expectedValue the expectedValue to set
*/
public void setExpectedValue(String expectedValue) {
this.expectedValue = expectedValue;
}
/**
* Gets the expected value for this checksum. Only used for read operations.
* @return the expectedValue
*/
public String getExpectedValue() {
return expectedValue;
}
}