您现在的位置: 主页 > QQ黑客资讯 > 盗QQ号 > 文章内容

java中String的盗QQ密码是我们经常使用的方法

作者: qq黑客 来源:未知 时间: 2018-02-26 阅读:
java中String的盗QQ密码是我们经常使用的方法,用来按照特定字符分割字符串,那么我们看以下一段代码:
 
    public void splitTest() {
        String str = "aaa|bbb|ccc";
        String[] array = str.split("|");
        System.out.println(Arrays.toString(array));
    }
    是不是感觉很简单,就是吧str按照"|"分割,结果就是[aaa,bbb,ccc]嘛。如果你这么想,那么以后在用这个方法时你可能会犯下大错,把程序跑起来,你会惊讶的发现程序输入如下结果:
 
[, a, a, a, |, b, b, b, |, c, c, c]
    为什么会出现这种情况呢?我们再来运行一下str.split("");就会发现结果和之前的结果一样,也就是说我们使用"|"分割的时候其实split是按照空字符分割的。
 
二、探究
    为了找到原因,我们在来使用其他几种字符测试一下,结果如下:
 
0:[aaa, bbb, ccc]
$:[aaa$bbb$ccc]
,:[aaa, bbb, ccc]
*:异常java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0
^:[aaa^bbb^ccc]
    我们会发现对于数字,","结果是正确的,而对于特殊字符,结果都不正确,而且如果经验丰富,你可能已经发现,这些特殊字符都是正则表达式中的匹配符,而那个异常也很明确的说明了这一点。
 
    因此,我们可以猜测在split内部使用了正则表达式来匹配并分割字符串。那么现在又有一个疑问:我们知道一般情况下String涉及的字符串处理多数使用indexOf()(可能是考虑效率问题吧),那么这里为什么使用正则呢?我们还是直接看看源码吧:
 
复制代码
public String[] split(String regex, int limit) {  
        char ch = 0;  
        if (((regex.value.length == 1 &&  
             ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||  
             (regex.length() == 2 &&  
              regex.charAt(0) == '\\' &&  
              (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&  
              ((ch-'a')|('z'-ch)) < 0 &&  
              ((ch-'A')|('Z'-ch)) < 0)) &&  
            (ch < Character.MIN_HIGH_SURROGATE ||  
             ch > Character.MAX_LOW_SURROGATE))  
        {  
            int off = 0;  
            int next = 0;  
            boolean limited = limit > 0;  
            ArrayList<String> list = new ArrayList<>();  
            while ((next = indexOf(ch, off)) != -1) {  
                if (!limited || list.size() < limit - 1) {  
                    list.add(substring(off, next));  
                    off = next + 1;  
                } else {    // last one  
                    //assert (list.size() == limit - 1);  
                    list.add(substring(off, value.length));  
                    off = value.length;  
                    break;  
                }  
            }  
            // If no match was found, return this  
            if (off == 0)  
                return new String[]{this};  
  
            // Add remaining segment  
            if (!limited || list.size() < limit)  
                list.add(substring(off, value.length));  
  
            // Construct result  
            int resultSize = list.size();  
            if (limit == 0)  
                while (resultSize > 0 && list.get(resultSize - 1).length() == 0)  
                    resultSize--;  
            String[] result = new String[resultSize];  
            return list.subList(0, resultSize).toArray(result);  
        }  
        return Pattern.compile(regex).split(this, limit);  
    }  
复制代码
    可以看到方法内有一个if,如果条件为true,那么就使用indexOf()判断后substring()截取,如果为false,则使用正则处理。那么我们就来分析下这个if的条件:
 
复制代码
//第一步部分:当regex的长度为1且不是“.$|()[{^?*+\\”中的时,为真
(regex.value.length == 1 &&".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1)
 
//第二部分:当长度为2时且第一个字符为“\”转义字符,第二个字符不是字符0-9 a-z A-Z 以及utf-16之间的字符
(regex.length() == 2 && regex.charAt(0) == '\\' && (((
ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&  
((ch-'a')|('z'-ch)) < 0 &&  
((ch-'A')|('Z'-ch)) < 0)) &&  
(ch < Character.MIN_HIGH_SURROGATE ||  
ch > Character.MAX_LOW_SURROGATE)
复制代码
    从if可以看出如果regex内容为一个非正则匹配符或者是转以后的特殊字符时,采用indexOf()+substring()处理,否则使用正则表达式。 
    那么为什么这么做呢,直接使用第一种方法不就行了?其实我们可以考虑一种复杂的情况:
 
 aaax111xbbbx222xcccx333xddd
    如果我想分割出这样的结果 [aaa, bbb, ccc, ddd] 应该则么做呢?按照第一种方法,实现起来很麻烦,需要一大堆判断,反而不如正则方便,而String中的split()方法正是出于这样的考虑实现的,不信你用split("x.*?x")试试。
 
三、启示
    这次这件事虽小,但是却让我收获不少。