有道翻译接口 破解

有道翻译 API

最近有些任务需要将中文翻译成英文,由于个人英文水平问题,每次都要打开好几个在线翻译网页,一句一句的丢进去,取最佳者为所用,甚是麻烦。
任务完成之后,就稍微研究了一下各个翻译接口(Github地址,求star),下面以 “有道翻译 API” 为例。

有道翻译官网提供了 API 接口,需要注册并付费才能使用,按照格式进行请求(JAVA DEMO),其中有一些参数:
API 参数介绍
注意 slat 和 sign 参数。从 JAVA DEMO 中可知,slat 随机数是通过获取系统时间得到的,而 sign 签名则是通过某个字符串的 md5 算法得到的,官网提供的 md5 算法代码如下:

/**
     * 生成32位MD5摘要
     * @param string
     * @return
     */
    public static String md5(String string) {
        if(string == null){
            return null;
        }
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'A', 'B', 'C', 'D', 'E', 'F'};
        byte[] btInput = string.getBytes();
        try{
            /** 获得MD5摘要算法的 MessageDigest 对象 */
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            /** 使用指定的字节更新摘要 */
            mdInst.update(btInput);
            /** 获得密文 */
            byte[] md = mdInst.digest();
            /** 把密文转换成十六进制的字符串形式 */
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (byte byte0 : md) {
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        }catch(NoSuchAlgorithmException e){
            return null;
        }
    }

本来按照上述操作就可以很顺利的利用 API 进行开发,关键是要收费啊,还是按字符数收费。接下来就开始了破解之路,实现 无需注册就可以使用 有道翻译 接口……

有道翻译 破解

用Chrome打开有道翻译首页,按F12键,在翻译框内输入一句话,点击翻译。
审查元素
可以看到有道翻译的 Request URL 和 Request Method,在往下看:
审查元素
从 From Data 中可以查看到许多参数。经过多次实验,发现发生改变的只有 i,salt 和 sign 三个参数值。其中 i 是要翻译的内容,salt 和 sign 的来历和作用前面已经介绍了。但在 API 中 sign 参数是带了 appKey(注册,后台生成) 的,我们没有这个。那么就需要研究一下如何生成 sign 的了。
在众多请求中,发现一段 js 代码,如下:
这里写图片描述
将这段代码格式化一下,搜索关键词 sign,如下:
这里写图片描述
通过上述的 js 代码可知,salt 参数是通过系统时间,加上一个 [1, 10] 的随机数得到的, sign = md5(固定字符串 + 待翻译内容 + salt + 固定字符串) 得到的。这样我们就可以通过代码进行请求了,代码如下:

public class YouDao {
    public static void main(String[] args) throws Exception {
        String from = "en";
        String to = "zh-CHS";
        String q = "Who am I? Where am I?";
        String url = "http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule";

        String u = "fanyideskweb";
        String d = q;
        long ctime = System.currentTimeMillis();
        String f = String.valueOf(ctime + (long)(Math.random() * 10 + 1));
        String c = "ebSeFb%=XZ%T[KZ)c(sy!";

        String sign = util.md5(u + d + f + c);

        Map<String, String> params = new HashMap<String, String>();
        params.put("i", q);
        params.put("from", from);
        params.put("to", to);
        params.put("smartresult", "dict");
        params.put("client", "fanyideskweb");
        params.put("salt", f);
        params.put("sign", sign);
        params.put("doctype", "json");
        params.put("version", "2.1");
        params.put("keyfrom", "fanyi.web");
        params.put("action", "FY_BY_CLICKBUTTION");
        params.put("typoResult", "false");

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost request = new HttpPost(util.getUrlWithQueryString(url, params));

//        request.setHeader("Accept","application/json, text/javascript, */*; q=0.01");
//        request.setHeader("Accept-Encoding","gzip, deflate");
//        request.setHeader("Accept-Language","zh-CN,zh;q=0.9");
//        request.setHeader("Connection","keep-alive");
//        request.setHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");
        request.setHeader("Cookie","OUTFOX_SEARCH_USER_ID_NCOO=1537643834.9570553; OUTFOX_SEARCH_USER_ID=1799185238@10.169.0.83; fanyi-ad-id=43155; fanyi-ad-closed=1; JSESSIONID=aaaBwRanNsqoobhgvaHmw; _ntes_nnid=07e771bc10603d984c2dc8045a293d30,1525267244050; ___rl__test__cookies=" + String.valueOf(ctime));
//        request.setHeader("Host","fanyi.youdao.com");
//        request.setHeader("Origin","http://fanyi.youdao.com");
        request.setHeader("Referer","http://fanyi.youdao.com/");
        request.setHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36");
//        request.setHeader("X-Requested-With","XMLHttpRequest");

        CloseableHttpResponse httpResponse = httpClient.execute(request);
        HttpEntity httpEntity = httpResponse.getEntity();
        String result = EntityUtils.toString(httpEntity, "UTF-8");
        EntityUtils.consume(httpEntity);    // 关闭
        httpResponse.close();

        String res[] = result.split("\"");
        StringBuilder resd = new StringBuilder();
        for (int i = 0; i < res.length; i++) {
            if (res[i].equals("tgt")) {
                resd.append(res[i + 2]);
            }
        }
        System.out.println(resd.toString());
    }

其中,md5() 和 getUrlWithQueryString() 可以利用 JAVA DEMO 提供的方法。

注意:对”http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule“发起请求时,需要设置cookie,否则会出现errorCode。在不设置 cookie 时,只能请求 “http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule“。

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页