假设有一个
String str = "sha256(12345sha256(abc)6789sha256(abc))abcdef";
如何以递归方式对该字符串中sha256(
和)
之间的所有内容进行哈希?我考虑正则表达式,但我不确定它是这种情况下的最佳工具。我想要的 - 首先是内在的价值是散列,然后是外部。
我只需要sha256()
来做这件事,但我认为对这个问题的回答是假设有另一个哈希函数(md5()
,sha1()
...)对社区有所帮助。
由于
答案 0 :(得分:1)
abstract class HashFunction{
public abstract String hash(String in);
}
class SHA256 extends HashFunction{
public String hash(String in){
//replace with a hashfunction
return "h<" + in + ">";
}
}
String str = "sha256(12345sha256(abc)6789sha256(abc))abcdef";
//map all available functions to their names
HashMap<String , HashFunction> functions = new HashMap<>();
functions.put("sha256" , new SHA256());
//create a list with the functionNames (not necassary, but simplifies a lot)
ArrayList<String> functionNames = new ArrayList<>();
functionNames.addAll(functions.keySet());
boolean functionFound = false;
do{//as long as functioncalls can be found proceed
int currentIndex = 0;
functionFound = false;
//search for all opening brackets in the function
while((currentIndex = str.indexOf('(' , currentIndex)) != -1){
int closeBracket = str.indexOf(')' , currentIndex + 1);
int openBracket = str.indexOf('(' , currentIndex + 1);
if(closeBracket == -1 && openBracket > closeBracket)
throw new Exception("Invalid syntax - missing bracket");
//should be replaced with a more specific exceptiontype
if(closeBracket < openBracket || openBracket == -1){
//the next closing bracket is before the next opening bracket -> the string can be used as input
functionFound = true;
//search for the functionname matching the one in str at the given position
final int curInd = currentIndex;
final String tmpStr = str;
Stream<String> matches = functionNames.stream().filter(n -> tmpStr.regionMatches(curInd - n.length() , n , 0 , n.length()));
Object[] tmp = matches.toArray();
if(tmp.length > 1)
throw new Exception("multiple matching hashfunctions");
if(tmp.length == 0)
throw new Exception("no matching hashfunction");
String f = (String) tmp[0];
HashFunction function = functions.get(f);
String input = str.substring(currentIndex + 1, closeBracket);
String hash = function.hash(input);
//replace hashfunction call with hash
String temp = str.substring(0 , currentIndex - f.length());
temp += hash;
temp += str.substring(closeBracket + 1);
str = temp;
//continue search at the end of the last replaced function
currentIndex = currentIndex - f.length() - input.length() + hash.length();
}else
//go to the next nested function call
currentIndex = openBracket - 1;
}
}while(functionFound);
像char(经过测试)一样工作。
答案 1 :(得分:1)
import java.io.IOException;
import org.apache.commons.codec.digest.DigestUtils;
public class Main {
public static void main(String[] args) throws IOException {
String str = "sha256(12345sha256(abc)6789sha256(abc))abcdef";
System.out.println(recursiveHash(str, str.length()));
}
public static String recursiveHash(String str, int lastSearchedIndex){
String tmp = str.substring(0, lastSearchedIndex);
int innerShaIndex = tmp.lastIndexOf("sha256(");
if(innerShaIndex != -1){
int bracketIndex = findCloseBracketIndex(str, innerShaIndex+7);
String innerSha = str.substring(innerShaIndex+7, bracketIndex);
String sha256hex = DigestUtils.sha256Hex(innerSha);
System.out.println(innerSha+"=="+sha256hex);
str = str.substring(0, innerShaIndex+7)+
sha256hex+
str.substring(bracketIndex);
str = recursiveHash(str, innerShaIndex);
}
return str;
}
public static int findCloseBracketIndex(String str, int startFrom){
int openBracketCount = -1;
for(int i = startFrom; i < str.length(); i++){
if(str.charAt(i) == '('){
if(openBracketCount == -1){
openBracketCount = 1;
}else{
openBracketCount++;
}
}else if(str.charAt(i) == ')'){
openBracketCount--;
if(openBracketCount <= -1){
return i;
}
}
}
return -1;
}
}