Java - 使用哈希函数进行递归字符串解析

时间:2015-04-13 10:24:53

标签: java algorithm parsing recursion hash

假设有一个

String str = "sha256(12345sha256(abc)6789sha256(abc))abcdef";

如何以递归方式对该字符串中sha256()之间的所有内容进行哈希?我考虑正则表达式,但我不确定它是这种情况下的最佳工具。我想要的 - 首先是内在的价值是散列,然后是外部。

我只需要sha256()来做这件事,但我认为对这个问题的回答是假设有另一个哈希函数(md5()sha1() ...)对社区有所帮助。

由于

2 个答案:

答案 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;
}

}