【Unity】手接「Google翻译」

2019-05-30  本文已影响0人  FCLoveShare

公司项目是海外的,新版本加入了翻译计划。google翻译推出了自己的API,不过是收费的。
以下是我实现的Unity版本的手接google翻译


核心接口

https://translate.google.cn/translate_a/single
            #if  UNITY_ANDROID
                headers.Add("User-Agent", "Mozilla/5.0 (Linux; U; Android 2.2.1; zh-cn; HTC_Wildfire_A3333 Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1");//android
            #else
                headers.Add("User-Agent", "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5");//ios 哈希表的数据格式
            #endif

坑: head里面这个代理是一定要加的,否则google会限制访问,且ios和android的代理是不一样的

            //将要发送的Post文本内容  
            string postData = string.Format("client=t&sl=auto&tl={1}&hl={0}&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&dt=at&ie=UTF-8&oe=UTF-8&ssel=6&tsel=3&kc=0&tk={3}&q={2}", fromLanguage, toLanguage, encodedStr,tk);  
            //将文本转为byte数组  
            byte[] bs = System.Text.UTF8Encoding.UTF8.GetBytes (postData);
主要参数 描述
sl auto 自动检测(可选其他的)
tl en 翻译目标语言 采用ISO-639-1代码
hl zh-CN 翻译本地语言 采用ISO-639-1代码
tk token,验签参数(成功的关键,下面会详细介绍怎么获取tk)
q 我是谁 翻译内容(经过 utf-8 encode 编码过的)

其他的参数就用原文就可以


获取tk

要想获取tkk,首先要获取tkk,然后用google提供的算法把所需要翻译的内容进行计算

  1. 获取tkk
    其实就是访问google翻译页面,解析html文件,找到tkk
    tkk不是固定的,一定时间内会自己刷新,所以需要重新获取
        IEnumerator InitTkk()
        {
            string tkkHtml = string.Empty;
            string url="https://translate.google.cn";
            
            System.Collections.Hashtable headers = new System.Collections.Hashtable();
            
            #if  UNITY_ANDROID
                headers.Add("User-Agent", "Mozilla/5.0 (Linux; U; Android 2.2.1; zh-cn; HTC_Wildfire_A3333 Build/FRG83D) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1");//android
            #else
                headers.Add("User-Agent", "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5");//ios 哈希表的数据格式
            #endif

            WWW www=new WWW(url,null,headers);
            yield return www;
            
            if(www.error==null){
                tkkHtml=www.text;
                tkk=GetTkk(tkkHtml);                
            }
        }

正则表达式解析html

        private string GetTkk(string tkkHtml){
            string tempStr="";
            try{
                Regex reg = new Regex(@"tkk:'(?<key>.*?)',");
                Match match = reg.Match(tkkHtml);
                tempStr = match.Groups["key"].Value;
            }
            catch (Exception ex)
            {
                _Global.Log("Error:"+ex);
            }
            return tempStr;
        }
  1. tk算法
    a是所需翻译的字符串
    google原js算法
function b(a, b) {
      for (var d = 0; d < b.length - 2; d += 3) {
           var c = b.charAt(d + 2),
               c = "a" <= c ? c.charCodeAt(0) - 87 : Number(c),
                c = "+" == b.charAt(d + 1) ? a >>> c : a << c,
            a = "+" == b.charAt(d) ? a + c & 4294967295 : a ^ c
       }
       return a
}

function tk(a,TKK) {
        for (var e = TKK.split("."), h = Number(e[0]) || 0, g = [], d = 0, f = 0; f < a.length; f++) {
            var c = a.charCodeAt(f);
            128 > c ? 
            g[d++] = c : (2048 > c ? 
            g[d++] = c >> 6 | 192 : (55296 == (c & 64512) && f + 1 < a.length && 56320 == (a.charCodeAt(f + 1) & 64512) ?
             (c = 65536 + ((c & 1023) << 10) + (a.charCodeAt(++f) & 1023), g[d++] = c >> 18 | 240, g[d++] = c >> 12 & 63 | 128) : g[d++] = c >> 12 | 224, g[d++] = c >> 6 & 63 | 128), g[d++] = c & 63 | 128)
        }
        a = h;
        for (d = 0; d < g.length; d++) a += g[d],a = b(a, "+-a^+6");
        a = b(a, "+-3^+b+-f");
        a ^= Number(e[1]) || 0;
        0 > a && (a = (a & 2147483647) + 2147483648);
        a %= 1E6;
        return a.toString() + "." + (a ^ h)
}

翻译c#算法

        string GetTK(string a)
        {
            string[] e = tkk.Split('.');
            int d = 0;
            int h = 0;
            int[] g = new int[a.Length * 3];
            h = tools.Number(e[0]);
            for (int f = 0; f < a.Length; f++)
            {
                int c = a.charCodeAt(f);
                if (128 > c)
                {
                    g[d++] = c;
                }
                else
                {
                    if (2048 > c)
                    {
                        g[d++] = c >> 6 | 192;
                    }
                    else
                    {
                        if (55296 == (c & 64512) && f + 1 < a.Length && 56320 == (a.charCodeAt(f + 1) & 64512))
                        {
                            c = 65536 + ((c & 1023) << 10) + a.charCodeAt(++f) & 1023;
                            g[d++] = c >> 18 | 240;
                            g[d++] = c >> 12 & 63 | 128;
                        }
                        else
                        {
                            g[d++] = c >> 12 | 224;
                            g[d++] = c >> 6 & 63 | 128;
                            
                        }
                    }
                    g[d++] = c & 63 | 128;
                }
            }
        
            List<int> g1=new List<int>();
            foreach(int x in g){
                if(x!=0)
                    g1.Add(x);
            }
            int[] g0=g1.ToArray();

            long aa = h;
            for (d = 0; d < g0.Length; d++)
            {
                aa += g0[d];
                aa = Convert.ToInt64(b(aa, "+-a^+6"));
            }
            aa = Convert.ToInt64(b(aa, "+-3^+b+-f"));
            long bb = aa ^ tools.Number(e[1]);
            aa = bb;
            aa = aa + bb;
            bb = aa - bb;
            aa = aa - bb;
            if (0 > aa)
            {
                aa = (aa & 2147483647) + 2147483648;
            }
            aa %= (long)1e6;
            return aa.ToString() + "." + (aa ^ h);
        }

        string b(long a, string b)
        {
            for (int d = 0; d < b.Length - 2; d += 3)
            {
                char c = b.charAt(d + 2);
                int c0 = 'a' <= c ? c.charCodeAt(0) - 87 : tools.Number(c);
                long c1 = '+' == b.charAt(d + 1) ? a >> c0 : a << c0;
                a = '+' == b.charAt(d) ? a + c1 & 4294967295 : a ^ c1;
            }
            a = tools.Number(a);
            return a.ToString();
        }

工具类

using UnityEngine;
using System.Collections;
using System;

public static class tools
{
    //实现js的charAt方法
    public static char charAt(this object obj, int index)
    {
          char[] chars= obj.ToString().ToCharArray();
           return chars[index];
     }
    //实现js的charCodeAt方法
    public static int charCodeAt(this object obj, int index)
    {
        char[] chars= obj.ToString().ToCharArray();
        return (int)chars[index];
    }

    //实现js的Number方法
    public static int Number(object cc)
    {
        try
        {
            long a= Convert.ToInt64(cc.ToString());
            int  b = a > 2147483647 ? (int)(a - 4294967296) : a < -2147483647 ? (int)(a + 4294967296) : (int)a;
            return b;
        }
        catch (Exception)
        {
            return 0;
        }
    }
}


感谢
@STOS(https://blog.csdn.net/u013070165/article/details/85096834

上一篇下一篇

猜你喜欢

热点阅读