[英]Java - recursive string parsing with hash functions
假设有一个
String str = "sha256(12345sha256(abc)6789sha256(abc))abcdef";
如何递归哈希字符串中sha256(
和)
之间的所有内容? 我考虑过正则表达式,但不确定这种情况下的最佳工具。 我想要的-首先是内部值是哈希,然后是外部值。
我只需要使用sha256()
来做这件事,但是我认为假设存在另一个哈希函数( md5()
, sha1()
...)可以解决这个问题,这对社区很有帮助。
谢谢
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);
像字符(经过测试)一样工作。
导入java.io.IOException;
导入org.apache.commons.codec.digest.DigestUtils;
公共班级主要{
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;
}
}
为了找到想要散列的子字符串,我确实建议使用正则表达式。 尝试递归替换与以下正则表达式的所有匹配项:
sha256\([^\(\)]*\)
(这将查找子字符串sha256(...)
,其中...
不包含任何其他方括号。)
为了包括更多的哈希函数,我建议为每个哈希函数添加一个新的正则表达式,并在递归中将匹配项替换为正确的哈希值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.