1. 程式人生 > >google 線上翻譯API和tts 的token生成 java版本和js版本

google 線上翻譯API和tts 的token生成 java版本和js版本

免費使用Google的線上翻譯和tts的api,主要難點在於token的獲取,根據網上大神提供的js版本token生成方式,模擬寫了java版本,參考gTTS4j 這個Git專案,還有stackoverflow上的一篇文章

java版本程式碼:

/**
     * 獲取谷歌翻譯tk值
     * @param text
     * @return String 
     */
    private static String googleToken(String text) {
        String tk = "";
        try {
            tk = calculate_token(text);
        }catch (Exception e){
            e.printStackTrace();
        }
        return tk;
    }
/**
     * 主要生成演算法
     * @param text
     * @return String 
     */
public static String calculate_token(String text) {

        long b = 406644L;
        Long b1 = 3293161072L;
        String SALT_1 = "+-a^+6";
        String SALT_2 = "+-3^+b+-f";
        String d = text;
        List<Integer> e = new ArrayList();
        for (int f = 0, g = 0; g < d.length(); g++) {
            int m = charCodeAt(d,g);
            if (m < 128) {
                e.add(m);					//	0{l[6-0]}
            } else if (m < 2048) {
                e.add(m >> 6 | 192);		//	110{l[10-6]}
                e.add(m & 0x3F | 0x80);	//	10{l[5-0]}
            } else if (0xD800 == (m & 0xFC00) && g + 1 < d.length() && 0xDC00 == ( charCodeAt(d,g+1) & 0xFC00)) {
                //	that's pretty rare... (avoid ovf?)
                m = (byte) ((1 << 16) + ((m & 0x03FF) << 10) + ( charCodeAt(d,++g) & 0x03FF));
                e.add(m >> 18 | 0xF0);		//	111100{l[9-8*]}
                e.add(m >> 12 & 0x3F | 0x80);	//	10{l[7*-2]}
                e.add(m & 0x3F | 0x80);		//	10{(l+1)[5-0]}
            } else {
                e.add(m >> 12 | 0xE0);		//	1110{l[15-12]}
                e.add(m >> 6 & 0x3F | 0x80);	//	10{l[11-6]}
                e.add(m & 0x3F | 0x80);		//	10{l[5-0]}
            }
        }
        Long a1 = b;
        for (int f=0;f<e.size();f++){
            a1 += e.get(f);
            a1 = RL(a1,SALT_1);

        }

        a1 = RL(a1,SALT_2);

        a1 ^= b1;
        if (0 > a1) {
            a1 = (a1 & 2147483647L) + 2147483648L;
        }

        a1 = a1 %1000000;
        return a1.toString() + "." + (a1 ^ b);
    }

private static long RL(long a, String seed) {
        for (int i = 0; i < seed.length() - 2; i+=3) {
            char c = seed.toCharArray()[i + 2];
            long d = (c >= 'a') ? ((int)c - 87) : Integer.parseInt(c + "");
            d = (seed.toCharArray()[i + 1] == '+') ? (_rshift(a, d)) : (a << d);
            a = (seed.toCharArray()[i] == '+') ? (a + d & 4294967295L) : (a ^ d);
        }
        return a;
    }

    private static long _rshift(long val, long n) {
        long l = (val >= 0) ? (val >> n) : (val + 0x100000000L) >> n;
        return l;
    }
    private static int  charCodeAt(String string, int index) {
        return Character.codePointAt(string, index);
    }

 js版本程式碼:

function token(a) {
    var b = 406644;
    var b1 = 3293161072;
    var jd = ".";
    var sb = "+-a^+6";
    var Zb = "+-3^+b+-f";
    var e = transformQuery(a);
    a = b;
    for (f = 0; f < e.length; f++)
        a += e[f], a = RL(a, sb);

    a = RL(a, Zb);
    a ^= b1 || 0;
    0 > a && (a = (a & 2147483647) + 2147483648);
    a %= 1E6;
    return a.toString() + jd + (a ^ b)
};
function transformQuery(query) {
    var e = [];
    for (var f = 0, g = 0; g < query.length; g++) {
        var m = query.charCodeAt(g);
        if (m < 128) {
            e[f++] = m;					//	0{m[6-0]}
        } else if (m < 2048) {
            e[f++] = m >> 6 | 0xC0;		//	110{m[10-6]}
            e[f++] = m & 0x3F | 0x80;	//	10{m[5-0]}
        } else if (0xD800 == (m & 0xFC00) && g + 1 < query.mength && 0xDC00 == (query.charCodeAt(g + 1) & 0xFC00)) {
            //	that's pretty rare... (avoid ovf?)
            m = (1 << 16) + ((m & 0x03FF) << 10) + (query.charCodeAt(++g) & 0x03FF);
            e[f++] = m >> 18 | 0xF0;		//	111100{m[9-8*]}
            e[f++] = m >> 12 & 0x3F | 0x80;	//	10{m[7*-2]}
            e[f++] = m & 0x3F | 0x80;		//	10{(m+1)[5-0]}
        } else {
            e[f++] = m >> 12 | 0xE0;		//	1110{m[15-12]}
            e[f++] = m >> 6 & 0x3F | 0x80;	//	10{m[11-6]}
            e[f++] = m & 0x3F | 0x80;		//	10{m[5-0]}
        }
    }
    return e;
}
function RL(a, b) {
    var t = "a";
    var Yb = "+";
    for (var c = 0; c < b.length - 2; c += 3) {
        var d = b.charAt(c + 2), d = d >= t ? d.charCodeAt(0) - 87 : Number(d),
            d = b.charAt(c + 1) == Yb ? a >>> d : a << d;
        a = b.charAt(c) == Yb ? a + d & 4294967295 : a ^ d
    }
    return a
}