字符串屏蔽算法

     字符串在编程过程中必不可少,程序中不同模块的交互也少不了传递字符串。

     有时候,我们可能有这样的需求:字符串中某个子字符串是个特殊的标记,在传输过程中会对程序造成干扰,必须屏蔽它。最常见的例子:发起GET请求时,URL上的参数中如果有&符号,可能会导致参数列表被截断,最终导致传参失败。

     遇到这种情况,我们首先能想到的是把参数加密,然后传输,最终处理的时候再解密,这样就巧妙的转换了特殊标记的表现形式,貌似可以解决问题。

     但是,你不能保证加密算法本身不会产生特殊标记,也就是说,万一加密后的字符串中又出现了特殊标记怎么办?

     因此,你不得不仔细筛选加密算法,确保不会冲突。但这种做法并不通用,如果特殊标记有变,你又要换算法了。

     今天小菜分享给大家一个字符串屏蔽算法,通过该算法,可以对字符串进行编码,进而屏蔽掉特殊标记。

举例说明:

     原始字符串: %&%1@4&af&&d%a&&%&45%&%&

     屏蔽&符号编码(escape("%&%1@4&af&&d%a&&%&45%&%&","&")): 10%1%4%2%0%3%0%1%3%1%0%%%1@4afd%a%45%%

     屏蔽&符号解码(unescape("10%1%4%2%0%3%0%1%3%1%0%%%1@4afd%a%45%%","&")): %&%1@4&af&&d%a&&%&45%&%&

算法代码:

 1 /**
 2  * 字符串特殊片段编码 
 3  * @author 杨元
 4  *
 5  */
 6 public class ReplaceExt {
 7     
 8     private static final String SPLIT_MARK="%";
 9     
10     /**
11      * 编码
12      * @param expression 要编码的原始字符串
13      * @param find 要编码的字符串片段,该参数为正则表达式,注意转义
14      * @return 如果出现异常,返回空字符串
15      */
16     public static String escape(String expression,String find){
17         
18         String result = "";
19         StringBuilder newExpression = new StringBuilder(64);
20         String[] expressionArray;
21         
22         try {
23             //按照指定字符串分割原始字符串
24             expressionArray = expression.split(find,-1);
25             //记录总分段数
26             newExpression.append(expressionArray.length);
27             newExpression.append(SPLIT_MARK);
28             //记录每段的长度
29             for(String s : expressionArray){
30                 newExpression.append(s.length());
31                 newExpression.append(SPLIT_MARK);
32             }
33             //记录每段的具体数据
34             for(String s : expressionArray){
35                 newExpression.append(s);
36             }
37             
38             result = newExpression.toString();
39             
40         } catch (Exception e) {
41             result = "";
42         }
43         
44         return result;
45     }
46     
47     /**
48      * 解码
49      * @param expression 要解码的编码字符串
50      * @param find 要还原的字符串片段
51      * @return 如果出现异常,返回原字符串
52      */
53     public static String unescape(String expression,String find){
54         
55         String result = "";
56         String[] expressionArray;
57         StringBuilder oldExpression = new StringBuilder(64);
58         String oldStr = "";
59         StringBuilder newExpression = new StringBuilder(64);
60         int allParts;
61         int start = 0;
62         int length = 0;
63         
64         try {
65             //用SPLIT_MARK分割已经编码的字符串
66             expressionArray = expression.split(SPLIT_MARK,-1);
67             //第一部分为总段数
68             allParts = Integer.valueOf(expressionArray[0]);
69             //构造原字符串
70             for(int i=allParts+1;i<expressionArray.length;i++){
71                 oldExpression.append(expressionArray[i]);
72                 oldExpression.append(SPLIT_MARK);
73             }
74             oldStr = oldExpression.substring(0, oldExpression.length()-SPLIT_MARK.length());
75             //循环获取每一段
76             for(int i=1;i<=allParts;i++){
77                 length = Integer.valueOf(expressionArray[i]);
78                 newExpression.append(oldStr.substring(start,start+length));
79                 newExpression.append(find);
80                 start += length;
81             }
82             //去掉多余部分
83             result = newExpression.substring(0,newExpression.length()-find.length());
84             
85         } catch (Exception e) {
86             result = expression;
87         }
88         
89         return result;
90     }
91     
92     public static void main(String[] args){
93         String testStr = "%&%1@4&af&&d%a&&%&45%&%&";
94         System.out.println(escape(testStr, "&"));
95         System.out.println(unescape(escape(testStr, "&"), "&"));
96     }
97 }

算法思路:

     既然要屏蔽字符串,就直接把要屏蔽的字符串从原始字符串中消除,为了能还原,必须记住消除的位置,因此要在原始字符串前加一个数据段,来记录消除位置信息。

     数据段以任意字符分割,小菜默认选用的%(读者可自行更换),第一部分是消除的总个数,其它部分是消除的位置。之所以记录消除总个数,是为了方便确定数据段边界。不能用某个特殊标记作为边界,因为你无法保证原始字符串中不出现这个特殊标记。

算法特点:

     ·安全稳定

     ·灵活易用

     ·编码短小精悍

     ·支持多重编码

     本算法仅仅是一个编码算法,用来屏蔽掉特殊标记,并不能起到加密的作用。

     希望这个小算法能给大家带来帮助,不当之处欢迎与我交流。

原文地址:https://www.cnblogs.com/iyangyuan/p/3526197.html