在ABE(基于属性的加密)中,访问控制树可以分为两种,其中一种为AND/OR组成的逻辑表达式,还有就是用阈值表示的形式。如:A OR(B AND C)这种。转化为阈值就是B C 2/2 A 1/2,意思就是B和C必须满足一个并且要满足A。下面两个树状图分别代表阈值和逻辑表达式的结构。因为实验的需要,今天主要是描述如何将逻辑表达式转化为阈值形式(例如A OR(B AND C)转化为B C 2/2 A 1/2)。
这里是用Java进行编程:
这里我们先分析一下:要做的工作主要分为三个函数,其中第三个步骤将调用前两个函数。
- 将字符串转化为单词数组,如:String={"A AND B AND C"} ——> List<String>={"A","AND","B","AND","C"}。意思是要将一串字符串进行分解。
- 将单词转化为阈值形式,如:List<String>={"A","AND","B","AND","C"} ——> String={"C B A 3of3"},我们将不含括号的一个逻辑表达式转换为阈值形式。
- 将逻辑表达式转化为阈值表达式:如:String={"D OR ( A AND ( B AND C AND E ) )"} ——> String={"E C B 3of3 A 2of2 D 1of2"},这个就是最终在主函数中调用的函数。这里将用到栈。
前面两个都很好编写。主要是最后一个,需要用到栈相关知识。那么这里简要阐述一下算法。当输出不为")"时,入栈。否则,出栈,直到遇到与")"匹配的"("。
还是举一个例子来说明,比较好理解。
假如我们输入的是D OR ( A AND ( F OR ( B AND C AND E ) ) ),步骤如下:
- 申请一个栈,简称为stack
- 首先判断输入字符串是否为")",如果不是则入栈。如:D OR ( A AND ( F OR ( B AND C AND E都依次入栈。
- 否则,将")"所匹配的"("之前的所有字符出栈,转化为一个逻辑表达式。如:当E入栈后,下一个即将入栈字符串为")",于是将B AND C AND E出栈,转化为E C B 3/3。然后删除现在栈顶的"("。将"E C B 3/3"入栈。继续上述步骤。下一个输入的又是")"于是将"E C B 3/3"出栈, OR,F出栈。删除现在栈顶的"(",将这三个字符串转化为E C B 3/3 F 1/2。并且入栈。继续,下一个输入的还是")",于是"E C B 3/3 F 1/2"出栈,AND,A出栈。删除现在栈顶的"(",将这三个字符串转化为E C B 3/3 F 1/2 A 2/2。并入栈。
- 检查stack是否为空,若是则结束,若不是,则将栈内元素出栈。如:将"E C B 3/3 F 1/2 A 2/2"出栈,OR,D出栈。将三个字符串转化为E C B 3/3 F 1/2 A 2/2 D 1/2。至此,转化完成。
现在附上代码:
package transform;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class Transform {
/**
* 此函数是将字符串转化为单词数组,如:
* String={"A AND B AND C"} ——> List<String>={"A","AND","B","AND","C"}
* @param A
* @return List<String>
*/
public List<String> stringToList(String A) {
List<String> predicate = new ArrayList<String>();
int beginIndex = 0;
for (int endIndex = 0; endIndex < A.length(); endIndex++) {
if (A.charAt(endIndex) != ' ') {
continue;
} else {
// System.out.println(beginIndex + " " + endIndex);
predicate.add(A.substring(beginIndex, endIndex));
beginIndex = endIndex + 1;
endIndex += 1;
}
}
predicate.add(A.substring(beginIndex));
return predicate;
}
/**
* 将单词转化为阈值形式,如:
* List<String>={"A","AND","B","AND","C"} ——> String={"C B A 3of3"}
* @param lStr
* @return String
*/
public String pTog(List<String> lStr) {
int andIndex = 0;
int orIndex = 0;
for (int i = 0; i < lStr.size(); i++) {
if (lStr.get(i).equals("AND")) {
andIndex++;
lStr.remove(i);
i--;
}
if (lStr.get(i).equals("OR")) {
orIndex++;
lStr.remove(i);
i--;
}
}
// System.out.println(andIndex);
// System.out.println("------------------------");
// for (String x : lStr) {
// System.out.println(x);
// }
if (andIndex > 0) {
lStr.add((andIndex + 1) + "of" + (andIndex + 1));
}
if (orIndex > 0) {
lStr.add(1 + "of" + (orIndex + 1));
}
String str = new String();
for (String x : lStr) {
str = str.concat(x + " ");
}
// System.out.println(str);
str = str.substring(0,str.length() - 1);//删除末尾空格
return str;
}
/**
* 此函数是将逻辑表达式转化为阈值表达式:如:
* String={"D OR ( A AND ( B AND C AND E ) )"} ——> String={"E C B 3of3 A 2of2 D 1of2"}
* @param A
* @return String
*/
public String transStack(String A) {
List<String> predicate = stringToList(A);
Stack<String> letter = new Stack<String>();
List<String> thresholdTemp=new ArrayList<String>();
int i = 0;
while (i < predicate.size()) {
if (!predicate.get(i).equals(")")) {
letter.push(predicate.get(i));
System.out.println("入栈:"+predicate.get(i));
}else{//即将要进栈栈顶元素为")"时
while(!letter.peek().equals("(")){//当没碰到"("时出栈,并放到thresholdTemp中
System.out.println("出栈:"+letter.peek());
thresholdTemp.add(letter.pop());
}
String tempLetter=pTog(thresholdTemp);
System.out.println(tempLetter);
thresholdTemp.clear();
letter.pop();//将"("移出栈
letter.push(tempLetter);
System.out.println("入栈:"+tempLetter);
}
i++;
}
while(!letter.empty()){
thresholdTemp.add(letter.pop());
}
String tempLetter=pTog(thresholdTemp);
return tempLetter;
}
}
现在写出一个测试类进行测试:
package transform;
public class TransformTest {
public static void main(String[] args) {
// TODO 自动生成的方法存根
String A="D OR ( A AND ( F OR ( B AND C AND E ) ) )";
Transform trans=new Transform();
String G=trans.transStack(A);
System.out.println(G);
}
}
控制台显示输出为:
输出结果为正确的。