[英]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.