为了注册一个当前可注册的最短的QQ英文账号邮箱,我做了什么?(2020.08.20编写,今天才发现文章没有发出来,一直在草稿箱)

声明:本文旨在分享分析问题和解决问题的心路历程,并未对QQ邮箱进行恶意攻击

  • 最近想着买个服务器自己搭个邮箱服务,但是当我看到服务器价格还是犹豫了。我放弃这个想法的真正原因是自己搭建的服务不能保证收发率、安全性、可用性、需要一定的财力和人力维护,所以我决定还是用现成的。
  • 考虑到域名长度和个人习惯我最终还是决定用QQ邮箱英文邮箱账号,但是我试了好几个都被注册了,但是我又不甘心用太长的,怎么办?

一、分析

当前目标是注册一个尽可能短的QQ英文邮箱账号,人工一个一个试基本不可行,这里很自然想到让计算机帮我批量试。
1、打开注册页面->F12,页面有一个输入框和一个按钮,大概猜测是点击按钮后获取输入框的值然后带上token之类的参数传JSON给后端,后端传回来一个状态码
在这里插入图片描述
2、点击Network清空旧请求后,随便输入一个aaa111验证操作一遍、发现已经被注册了,在下面找发现没有Json请求,我猜错了
在这里插入图片描述
3、查看这几个成功的请求,发现有一个html的GET请求,请求路径上带有我们输入的参数aaa111!原来是直接从服务端拿到了一个新的页面
在这里插入图片描述

4、看他原来还有个验证码,但是不知道为啥给去掉了,而且这边请求时还能收到这个验证码的图片,但是请求参数没有要求带上验证码,那这就更简单了!我们甚至不需要用AI模型对验证码图片进行机器识别。
在这里插入图片描述
5、多试几次发现:

  • 每次请求只有要查询的参数alias不同,其他的都是固定的
    在这里插入图片描述
  • 每次查询系统都会更新Cookei的qm_verifyimagesession,下一次查询需要带上这次的qm_verifyimagesession
    在这里插入图片描述
  • 账号可用的页面上有恭喜两个字,其他页面均没有这两个字,页面并没有类型的标志

二、解决

经过上面的分析,我们很容易想到一个思路:用程序发送get请求,把所有合法的参数都试验一次,如果收到的html页面里有恭喜两个字就判为没有注册。
1、参数的穷举:查看参数的命名规则如下:
在这里插入图片描述
这个问题和全排列很像,而且更简单,没有特别的约束,这里我封装了一个工具类RegisterUtil并实现了一个方法getAllPerm,该方法的方法签名为:getAllPerm(char[] chars, int minLength, int maxLength)
其中char数组包含了我们所有可用的字符,minLength是期望的排列串的最小长度,maxLength是期望的排列串的最大长度,代码如下:

/**
 * 获取当前字符数组的所有排列串结果集
 * @param chars 排列串可用的字符数组
 * @param minLength 排列串最小长度
 * @param maxLength 排列串最大长度
 * @return 所有符合条件的排列串结果集
 */
public static ArrayList<String> getAllPerm(char[] chars, int minLength, int maxLength) {
   
    //存放所有满足条件的序列
    ArrayList<String> result = new ArrayList<>();

    for (int i = minLength; i <= maxLength; i++) {
   
        //初始排列串
        String temp = "";
        //递归获取所有排列
        perm(chars, i, temp, result);
    }

    //返回结果集
    return result;
}

getAllPerm方法中的perm(char[] chars, int length, String temp, ArrayList<String> result)是一个递归方法,第一个参数还是getAllPerm方法中的第一个参数,第二个参数length是(递归深度)排列串的长度,第三个参数temp是当前排列串的中间引用变量,第四个参数result负责存放所有合法排列串的集合。
结合上文列出的命名规则,我在方法体内部加入了所有特殊情况的判断,具体代码如下:

    /**
     * 递归组合排列串(数字不能作为开头)
     * @param chars 排列串可用的字符数组
     * @param length 排列串的长度
     * @param temp 当前排列串
     * @param result 符合条件的排列串结果集合
     */
    private static void perm(char[] chars, int length, String temp, ArrayList<String> result) {
   
        //获取当前序列串长度
        int len = temp.length();
        //递归出口字符串达到规定长度
        if(len == length) {
   
            System.out.println(temp);
            result.add(temp);
        } else {
   
            //从字符数组中依次取出可用字符并充当序列的第temp.length() + 1个字符
            for (char c : chars) {
   
                //如果是第一个
                if (len == 0) {
   
                    //如果不是字母开头
                    if (!Character.isLowerCase(c
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值