Last active
April 13, 2019 00:39
-
-
Save holly-hacker/2e9521532d6196330e52b2a276572db6 to your computer and use it in GitHub Desktop.
Revisions
-
holly-hacker revised this gist
Apr 13, 2019 . 1 changed file with 57 additions and 15 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,26 +1,68 @@ namespace HoLLy.DiscordBot.Sandwich.Tools { public static class GoogleTranslate { private const string TranslateEndpoint = "https://translate.google.com/translate_a/single"; private const string TtsEndpoint = "https://translate.google.com/translate_tts"; public static readonly Dictionary<string, string> Languages = new Dictionary<string, string> { {"auto", "Automatic"}, {"af", "Afrikaans"}, {"sq", "Albanian"}, {"am", "Amharic"}, {"ar", "Arabic"}, {"hy", "Armenian"}, {"az", "Azerbaijani"}, {"eu", "Basque"}, {"be", "Belarusian"}, {"bn", "Bengali"}, {"bs", "Bosnian"}, {"bg", "Bulgarian"}, {"ca", "Catalan"}, {"ceb", "Cebuano"}, {"ny", "Chichewa"}, {"zh-cn", "Chinese Simp."}, {"zh-tw", "Chinese Trad."}, {"co", "Corsican"}, {"hr", "Croatian"}, {"cs", "Czech"}, {"da", "Danish"}, {"nl", "Dutch"}, {"en", "English"}, {"eo", "Esperanto"}, {"et", "Estonian"}, {"tl", "Filipino"}, {"fi", "Finnish"}, {"fr", "French"}, {"fy", "Frisian"}, {"gl", "Galician"}, {"ka", "Georgian"}, {"de", "German"}, {"el", "Greek"}, {"gu", "Gujarati"}, {"ht", "Haitian Creole"}, {"ha", "Hausa"}, {"haw", "Hawaiian"}, {"iw", "Hebrew"}, {"hi", "Hindi"}, {"hmn", "Hmong"}, {"hu", "Hungarian"}, {"is", "Icelandic"}, {"ig", "Igbo"}, {"id", "Indonesian"}, {"ga", "Irish"}, {"it", "Italian"}, {"ja", "Japanese"}, {"jw", "Javanese"}, {"kn", "Kannada"}, {"kk", "Kazakh"}, {"km", "Khmer"}, {"ko", "Korean"}, {"ku", "Kurdish"}, {"ky", "Kyrgyz"}, {"lo", "Lao"}, {"la", "Latin"}, {"lv", "Latvian"}, {"lt", "Lithuanian"}, {"lb", "Luxembourgish"}, {"mk", "Macedonian"}, {"mg", "Malagasy"}, {"ms", "Malay"}, {"ml", "Malayalam"}, {"mt", "Maltese"}, {"mi", "Maori"}, {"mr", "Marathi"}, {"mn", "Mongolian"}, {"my", "Myanmar"}, {"ne", "Nepali"}, {"no", "Norwegian"}, {"ps", "Pashto"}, {"fa", "Persian"}, {"pl", "Polish"}, {"pt", "Portuguese"}, {"ma", "Punjabi"}, {"ro", "Romanian"}, {"ru", "Russian"}, {"sm", "Samoan"}, {"gd", "Scots Gaelic"}, {"sr", "Serbian"}, {"st", "Sesotho"}, {"sn", "Shona"}, {"sd", "Sindhi"}, {"si", "Sinhala"}, {"sk", "Slovak"}, {"sl", "Slovenian"}, {"so", "Somali"}, {"es", "Spanish"}, {"su", "Sundanese"}, {"sw", "Swahili"}, {"sv", "Swedish"}, {"tg", "Tajik"}, {"ta", "Tamil"}, {"te", "Telugu"}, {"th", "Thai"}, {"tr", "Turkish"}, {"uk", "Ukrainian"}, {"ur", "Urdu"}, {"uz", "Uzbek"}, {"vi", "Vietnamese"}, {"cy", "Welsh"}, {"xh", "Xhosa"}, {"yi", "Yiddish"}, {"yo", "Yoruba"}, {"zu", "Zul"}, }; private static string cachedTtk; private static int UnixEpoch => (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds; public static bool SupportsLanguage(string dst) => Languages.ContainsKey(dst); public static async Task<string> Translate(string query, string to = "en", string from = "auto") { string token = GenerateToken(query, await GetTTK()); string dt = string.Join("&", new [] { "at", "bd", "ex", "ld", "md", "qca", "rw", "rm", "ss", "t" }.Select(x => $"dt={x}")); string queryString = $"?client=webapp&sl={from}&tl={to}&hl={to}&{dt}&pc=1&otf=1&ssel=0&tsel=0&kc=1&tk={token}&q={WebUtility.UrlEncode(query)}"; // adding user-agent somehow fixes unicode inputs. var wc = new WebClient { Headers = { [HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0" } }; string jsonData = await wc.DownloadStringTaskAsync(TranslateEndpoint + queryString); var data = (JArray)JsonConvert.DeserializeObject(jsonData); return string.Join(string.Empty, data[0].Select(x => ((JValue)x[0]).Value?.ToString())); } public static async Task<byte[]> TextToSpeech(string query, string language = "en") { string token = GenerateToken(query, await GetTTK()); string queryString = $"?ie=UTF-8&q={WebUtility.UrlEncode(query)}&tl={language}&total=1&idx=0&textlen={query.Length-1}&tk={token}&client=webapp"; // adding user-agent somehow fixes unicode inputs. var wc = new WebClient { Headers = { [HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefox/60.0" } }; return await wc.DownloadDataTaskAsync(TtsEndpoint + queryString); } private static async Task<string> GetTTK() { if (cachedTtk is null || Convert.ToInt32(cachedTtk.Split('.')[0]) != UnixEpoch / (1000*60*60)) cachedTtk = await DownloadTTK(); return cachedTtk; } private static async Task<string> DownloadTTK() @@ -32,7 +74,7 @@ private static async Task<string> DownloadTTK() internal static string GenerateToken(string inputString, string tkk) { string[] tkkSplit = tkk.Split('.'); long tkkFirst = Convert.ToInt64(tkkSplit[0]); var crypted = new List<int>(); for (var i = 0; i < inputString.Length; i++) { int c = inputString[i]; @@ -61,17 +103,17 @@ internal static string GenerateToken(string inputString, string tkk) param = evalKey(param + i, "+-a^+6"); } param = evalKey(param, "+-3^+b+-f"); param ^= Convert.ToInt64(tkkSplit[1]); uint newParam = (uint)param; newParam %= 1000000; return newParam + "." + (newParam ^ tkkFirst); long evalKey(long input, string key) { Debug.WriteLine("=== " + input); for (int i = 0; i < key.Length - 2; i += 3) { char d1 = key[i + 2]; int d2 = 'a' <= d1 ? d1 - 0x57 : Convert.ToInt32(d1.ToString()); long d = '+' == key[i + 1] ? (int)((uint)input >> d2) : input << d2; input = '+' == key[i] ? (int)(input + d & 0xFFFFFFFF) : input ^ d; } -
holly-hacker created this gist
Apr 8, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,83 @@ namespace HoLLy.DiscordBot.Sandwich.Tools { public static class Translator { private const string ApiEndpoint = "https://translate.google.com/translate_a/single"; private static string cachedTtk; private static int UnixEpoch => (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds; public static async Task<string> Translate(string query, string to = "en", string from = "auto") { if (cachedTtk is null || Convert.ToInt32(cachedTtk.Split('.')[0]) != UnixEpoch / (1000*60*60)) cachedTtk = await DownloadTTK(); string token = GenerateToken(query, cachedTtk); string dt = string.Join("&", new [] { "at", "bd", "ex", "ld", "md", "qca", "rw", "rm", "ss", "t" }.Select(x => $"dt={x}")); string queryString = $"?client=webapp&sl={from}&th={to}&hl={to}&{dt}&otf=2&ssel=0&tsel=0&kc=2&tk={token}&q={query}"; string jsonData = await new WebClient().DownloadStringTaskAsync(ApiEndpoint + queryString); var data = (JArray)JsonConvert.DeserializeObject(jsonData); var y = (JValue)data[0][0][0]; return (string)y.Value; } private static async Task<string> DownloadTTK() { var resp = await new WebClient().DownloadStringTaskAsync("https://translate.google.com"); return Regex.Match(resp, @"tkk:\'(\d+\.\d+)\'").Groups[1].Value; } internal static string GenerateToken(string inputString, string tkk) { string[] tkkSplit = tkk.Split('.'); int tkkFirst = Convert.ToInt32(tkkSplit[0]); var crypted = new List<int>(); for (var i = 0; i < inputString.Length; i++) { int c = inputString[i]; if (c < 0x80) crypted.Add(c); else { if (c < 0x800) { crypted.Add(c >> 6 | 0xC0); } else { if (0xD800 == (c & 0xFC00) && i + 1 < inputString.Length && 0xDC00 == (inputString[i + 1] & 0xFC00)) { c = 0x10000 + ((c & 0x3FF) << 10) + (inputString[++i] & 0x3FF); crypted.Add(c >> 18 | 0xF0); crypted.Add(c >> 12 & 0x3F | 0x80); } else { crypted.Add(c >> 12 | 0xE0); crypted.Add(c >> 6 & 0x3F | 0x80); } } crypted.Add(c & 0x3F | 0x80); } } var param = tkkFirst; foreach (int i in crypted) { param = evalKey(param + i, "+-a^+6"); } param = evalKey(param, "+-3^+b+-f"); param ^= Convert.ToInt32(tkkSplit[1]); uint newParam = (uint)param; newParam %= 1000000; return newParam + "." + (newParam ^ tkkFirst); int evalKey(int input, string key) { Debug.WriteLine("=== " + input); for (int i = 0; i < key.Length - 2; i += 3) { char d1 = key[i + 2]; int d = 'a' <= d1 ? d1 - 0x57 : Convert.ToInt32(d1.ToString()); d = '+' == key[i + 1] ? (int)((uint)input >> d) : input << d; input = '+' == key[i] ? (int)(input + d & 0xFFFFFFFF) : input ^ d; } Debug.WriteLine(""); return input; } } } }