zoukankan      html  css  js  c++  java
  • 字符串屏蔽算法

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

         有时候,我们可能有这样的需求:字符串中某个子字符串是个特殊的标记,在传输过程中会对程序造成干扰,必须屏蔽它。最常见的例子:发起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 }

    算法思路:

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

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

    算法特点:

         ·安全稳定

         ·灵活易用

         ·编码短小精悍

         ·支持多重编码

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

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

  • 相关阅读:
    LeetCode 905 按奇偶排序数组
    LeetCode 46 全排列
    Django 2随便使用笔记-Day01
    Python函数化编程整理
    Oracle解锁表笔记
    springboot(1)使用SpringBoot基础HTTP接口GET|POST|DELETE|PUT请求
    什么是Restful API
    C# 生成条形码BarCode 128
    ADB shell 的一般操作
    遇到“未能从程序集XXXX...加载类型XXX”的问题
  • 原文地址:https://www.cnblogs.com/iyangyuan/p/3526197.html
Copyright © 2011-2022 走看看