unity免费使用谷歌翻译(使用tk值,防止数量限制的错误)

如果直接使用

string url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl="
                    + sourceLang + "&tl=" + targetLang + "&dt=t&q=" + UnityWebRequest.EscapeURL(sourceText);

这种url去谷歌翻译那里获取翻译的话,会有限制,因为没有token值,所以很容易会给谷歌那边屏蔽ip,无法再翻译。后面找了一下资料,发现有些是使用了tk值的方式来访问谷歌翻译,经过验证,很频繁(每隔0.2s翻译一条)翻译,翻译是上万条也没出现给限制的情况。这种方法的难点就在tk值的获取,其实tk值在使用GET方式访问https://translate.google.cn的时候就可以获取到,但是这个tk值还需要做一些处理,才能重新使用。下面说下怎么获取。

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using YIMEngine;
using System;
using System.Text.RegularExpressions;
using System.Collections.Generic;

public class Translate
{
    protected struct ExternalKey
    {
        /// <summary>
        /// Total hours
        /// </summary>
        public long Time { get; }

        /// <summary>
        /// Token value
        /// </summary>
        public long Value { get; }

        /// <param name="time">Unix-formatted total hours</param>
        /// <param name="value">Token value</param>
        public ExternalKey(long time, long value)
        {
            Time = time;
            Value = value;
        }
    }

    protected static int UnixTotalHours
    {
        get
        {
            DateTime unixTime = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            return (int)DateTime.UtcNow.Subtract(unixTime).TotalHours;
        }
    }
    // We have use googles own api built into google Translator.
    public static IEnumerator Process(string targetLang, string sourceText, System.Action<string, int> result, int times)
    {
        yield return Process("auto", targetLang, sourceText, result, times);
    }

    // Exactly the same as above but allow the user to change from Auto, for when google get's all Jerk Butt-y
    public static IEnumerator Process(string sourceLang, string targetLang, string sourceText, System.Action<string, int> result,
        int times)
    {
        //第一步,先使用GET方式访问谷歌翻译,拿到html的tk值
        string urlte = "https://translate.google.cn";
        UnityWebRequest request1 = new UnityWebRequest(urlte, "GET");

        request1 .SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
        request1 .downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
        request1 .useHttpContinue = false;//应对某些机型的errorCallback with error=java.io.EOFException
        yield return request1.SendWebRequest();
        if (request1.isNetworkError || request1.isHttpError)
        {
            Debug.LogError("获取服务器列表失败 = " + request1.error);
            result.Invoke("", times);
            yield break;
        }

        long tkk = 0;

        try
        {
            //这个就是返回的初始tk值
            var tkkText = request1.downloadHandler.text.GetTextBetween(@"tkk:'", "',");

            if (tkkText == null)
            {
                result.Invoke("", times);
            }

            var splitted = tkkText.Split('.');
            if (splitted.Length != 2 || !long.TryParse(splitted[1], out tkk))
            {
                result.Invoke("", times);
            }

        }
        catch (ArgumentException)
        {
            result.Invoke("", times);
        }

        var currentExternalKey = new ExternalKey(UnixTotalHours, tkk);
        long time = DecrypthAlgorythm(sourceText, currentExternalKey);

        string tk = time.ToString() + '.' + (time ^ currentExternalKey.Time);

        string address = "https://translate.google.cn/translate_a/single";
        string url =$"{ address}" + "?" + 
                    $"sl={sourceLang}&" +
                    $"tl={targetLang}&" +
                    $"hl={sourceLang}&" +
                    $"q={UnityWebRequest.EscapeURL(sourceText)}&" +
                    $"tk={tk}&" +
                    "client=t&" +
                    "dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&" +
                    "ie=UTF-8&" +
                    "oe=UTF-8&" +
                    "otf=1&" +
                    "ssel=0&" +
                    "tsel=0&" +
                    "kc=7";
        //Debug.Log("地址=" + url);
        //string url = string.Format("https://translate.google.cn/translate_a/single?client=t&sl={0}&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=" + tk + "&q={2}", sourceLang, targetLang, UnityWebRequest.EscapeURL(sourceText));
        /*        string url = "https://translate.googleapis.com/translate_a/single?client=gtx&sl="
                    + sourceLang + "&tl=" + targetLang + "&dt=t&q=" + UnityWebRequest.EscapeURL(sourceText);*/
        UnityWebRequest request = new UnityWebRequest(url, "GET");
        //request.SetRequestHeader("Content-Type", "application/json;charset=utf-8");
        request.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36");
        request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
        request.useHttpContinue = false;//应对某些机型的errorCallback with error=java.io.EOFException
        yield return request.SendWebRequest();
        if (request.isNetworkError || request.isHttpError)
        {
            Debug.LogError("获取服务器列表失败 = " + request.error);
            result.Invoke("", times);
            yield break;
        }
        
        JsonData jsonData = JsonMapper.ToObject(request.downloadHandler.text);
        string translatedText = jsonData[0][0][0].ToString();
        //Debug.Log("返回的text=" + request.downloadHandler.text);
        Debug.Log("解析后=" + translatedText);
        result.Invoke(translatedText, times);
    }

    private static long DecrypthAlgorythm(string source, ExternalKey CurrentExternalKey)
    {
        List<long> code = new List<long>();

        for (int g = 0; g < source.Length; g++)
        {
            int l = source[g];
            if (l < 128)
            {
                code.Add(l);
            }
            else
            {
                if (l < 2048)
                {
                    code.Add(l >> 6 | 192);
                }
                else
                {
                    if (55296 == (l & 64512) && g + 1 < source.Length && 56320 == (source[g + 1] & 64512))
                    {
                        l = 65536 + ((l & 1023) << 10) + (source[++g] & 1023);
                        code.Add(l >> 18 | 240);
                        code.Add(l >> 12 & 63 | 128);
                    }
                    else
                    {
                        code.Add(l >> 12 | 224);
                    }
                    code.Add(l >> 6 & 63 | 128);
                }
                code.Add(l & 63 | 128);
            }
        }

        long time = CurrentExternalKey.Time;

        foreach (long i in code)
        {
            time += i;
            Xr(ref time, "+-a^+6");
        }

        Xr(ref time, "+-3^+b+-f");

        time ^= CurrentExternalKey.Value;

        if (time < 0)
            time = (time & int.MaxValue) + 2147483648;

        time %= (long)1e6;

        return time;
    }

    private static void Xr(ref long a, string b)
    {
        for (int c = 0; c < b.Length - 2; c += 3)
        {
            long d = b[c + 2];

            d = 'a' <= d ? d - 87 : (long)char.GetNumericValue((char)d);
            d = '+' == b[c + 1] ? (long)((ulong)a >> (int)d) : a << (int)d;
            a = '+' == b[c] ? a + d & 4294967295 : a ^ d;
        }
    }
}

下面是string的拓展方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

static class StringExtension
{
    internal static string GetTextBetween(this string src, string from, string to, int startIndex = 0)
    {
        if (src == null)
            throw new ArgumentNullException(nameof(src));
        if (from == null)
            throw new ArgumentNullException(nameof(from));
        if (to == null)
            throw new ArgumentNullException(nameof(to));
        if (startIndex < 0 || startIndex > src.Length - 1)
            throw new ArgumentOutOfRangeException(nameof(to));

        int index = src.IndexOf(from, startIndex, StringComparison.Ordinal);
        if (index == -1)
            return null;

        int index2 = src.IndexOf(to, index, StringComparison.Ordinal);
        if (index2 == -1)
            return null;

        var result = src.Substring(index + from.Length, index2 - index - from.Length);
        return result;
    }


    internal static string ToCamelCase(this string src)
    {
        string[] words = src.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

        return string.Concat(words.Select(word
            => char.ToUpper(word[0]) + word.Substring(1).ToLower()));
    }

}
 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值