/*******************************************************************************
 * Copyright (c) 2015 Eclipse RDF4J contributors, Aduna, and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Distribution License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *******************************************************************************/
package org.eclipse.rdf4j.query.algebra.evaluation.function.hash;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.eclipse.rdf4j.model.Literal;
import org.eclipse.rdf4j.model.Value;
import org.eclipse.rdf4j.model.ValueFactory;
import org.eclipse.rdf4j.query.algebra.evaluation.ValueExprEvaluationException;
import org.eclipse.rdf4j.query.algebra.evaluation.function.Function;

/**
 * Abstract hash function
 * 
 * @author jeen
 */
public abstract class HashFunction implements Function {

	protected String hash(String text, String algorithm)
		throws NoSuchAlgorithmException
	{
		byte[] hash = MessageDigest.getInstance(algorithm).digest(text.getBytes());
		BigInteger bi = new BigInteger(1, hash);
		String result = bi.toString(16);
		if (result.length() % 2 != 0) {
			return "0" + result;
		}
		return result;
	}

	public abstract Literal evaluate(ValueFactory valueFactory, Value... args)
		throws ValueExprEvaluationException;

}

@@ -556,37 +556,8 @@
 h;%0A%0A
-import java.math.BigInteger;%0A
 impo
@@ -1020,16 +1020,278 @@
 ction %7B%0A
+private final String HEX = %220123456789abcdef%22;%0A%09%0A%09/**%0A%09 * Calculate hash value, represented as hexadecimal string.%0A%09 * %0A%09 * @param text text%0A%09 * @param algorithm name of the hash algorithm%0A%09 * @return hexadecimal string%0A%09 * @throws NoSuchAlgorithmException %0A%09 */
 %0A%09protec
@@ -1456,168 +1456,297 @@
 ));%0A
+%0A
 %09%09
-BigInteger bi = new BigInteger(1, hash);%0A%09%09String result = bi.toString(16);%0A%09%09if (result.length() %25 2 != 0) %7B%0A%09%09%09return %220%22 + result;%0A%09%09%7D%0A%09%09return result;%0A%09%7D%0A
+// convert to hexadecimal representation, with leading zeros%0A%09%09char%5B%5D hex = new char%5Bhash.length * 2%5D;%0A%09%09for (int i = 0, j = 0; i %3C hex.length; ) %7B%0A%09%09%09hex%5Bi++%5D = HEX.charAt((hash%5Bj%5D & 0xF0) %3E%3E%3E 4);%0A%09%09%09hex%5Bi++%5D = HEX.charAt(hash%5Bj++%5D & 0x0F);%0A%09%09%7D%0A%09%09return new String(hex);%0A%09%7D%0A%0A%09@Override
 %0A%09pu
@@ -1857,11 +1857,10 @@
 eption;%0A
-%0A
 %7D%0A

Convert bytes to hex string with leading zeros