Skip to content

Commit 4d1c6c1

Browse files
committed
Attempted to add tk parameter for Google translate. Note: Bugs present.
1 parent d08af0a commit 4d1c6c1

1 file changed

Lines changed: 156 additions & 19 deletions

File tree

src/main/java/com/darkprograms/speech/translator/GoogleTranslate.java

Lines changed: 156 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,16 @@
22

33
import java.io.IOException;
44
import java.io.Reader;
5+
import java.io.UnsupportedEncodingException;
56
import java.net.URL;
67
import java.net.URLConnection;
78
import java.net.URLEncoder;
89
import java.nio.charset.Charset;
10+
import java.text.ParseException;
11+
import java.text.SimpleDateFormat;
12+
import java.util.ArrayList;
13+
import java.util.Date;
14+
import java.util.List;
915
import java.util.Locale;
1016

1117
/***************************************************************************************************************
@@ -17,17 +23,17 @@
1723
* @author Aaron Gokaslan (Skylion)
1824
***************************************************************************************************************/
1925
public final class GoogleTranslate { //Class marked as final since all methods are static
20-
26+
2127
/**
2228
* URL to query for Translation
2329
*/
24-
private final static String GOOGLE_TRANSLATE_URL = "http://translate.google.com/translate_a/t?client=t";
30+
private final static String GOOGLE_TRANSLATE_URL = "http://translate.google.com/translate_a/t";
2531

2632
/**
2733
* Private to prevent instantiation
2834
*/
2935
private GoogleTranslate(){};
30-
36+
3137
/**
3238
* Converts the ISO-639 code into a friendly language code in the user's default language
3339
* For example, if the language is English and the default locale is French, it will return "anglais"
@@ -38,34 +44,69 @@ public final class GoogleTranslate { //Class marked as final since all methods a
3844
public static String getDisplayLanguage(String languageCode){
3945
return (new Locale(languageCode)).getDisplayLanguage();
4046
}
41-
47+
48+
/** Completes the complicated process of generating the URL
49+
* @param sourceLanguage The source language
50+
* @param targetLanguage The target language
51+
* @param text The text that you wish to generate
52+
* @return The generated URL as a string.
53+
*/
54+
private static String generateURL(String sourceLanguage, String targetLanguage, String text) throws UnsupportedEncodingException{
55+
String encoded = URLEncoder.encode(text, "UTF-8"); //Encode
56+
StringBuilder sb = new StringBuilder();
57+
sb.append(GOOGLE_TRANSLATE_URL);
58+
sb.append("?client=t"); //The client parameter
59+
sb.append("&hl=en"); //The language of the UI?
60+
sb.append("&sl="); //Source language
61+
sb.append(sourceLanguage);
62+
sb.append("&tl="); //Target language
63+
sb.append(targetLanguage);
64+
sb.append("&text=");
65+
sb.append(encoded);
66+
sb.append("&multires=1");//Necessary but unknown parameters
67+
sb.append("&otf=0");
68+
sb.append("&pc=0");
69+
sb.append("&trs=1");
70+
sb.append("&ssel=0");
71+
sb.append("&tsel=0");
72+
sb.append("&sc=1");
73+
sb.append("&ie=UTF-8"); //Input encoding
74+
sb.append("&oe=UTF-8"); //Output encoding
75+
sb.append("&tk="); //Token authentication parameter
76+
sb.append(generateToken(encoded));
77+
return sb.toString();
78+
}
79+
4280
/**
4381
* Automatically determines the language of the original text
4482
* @param text represents the text you want to check the language of
4583
* @return The ISO-639 code for the language
4684
* @throws IOException if it cannot complete the request
4785
*/
4886
public static String detectLanguage(String text) throws IOException{
49-
String encoded = URLEncoder.encode(text, "UTF-8"); //Encodes the string
50-
URL url = new URL(GOOGLE_TRANSLATE_URL + "&text=" + encoded); //Generates URL
87+
String urlText = generateURL("auto", "en", text);
88+
URL url = new URL(urlText); //Generates URL
5189
String rawData = urlToText(url);//Gets text from Google
5290
return findLanguage(rawData);
5391
}
54-
55-
92+
93+
5694
/**
5795
* Automatically translates text to a system's default language according to its locale
5896
* Useful for creating international applications as you can translate UI strings
97+
* @see GoogleTranslate#translate(String, String, String)
5998
* @param text The text you want to translate
6099
* @return The translated text
61100
* @throws IOException if cannot complete request
62101
*/
63102
public static String translate(String text) throws IOException{
64103
return translate(Locale.getDefault().getLanguage(), text);
65104
}
66-
105+
67106
/**
68-
* Automatically detects language and translate to the targetLanguage
107+
* Automatically detects language and translate to the targetLanguage.
108+
* Allows Google to determine source language
109+
* @see GoogleTranslate#translate(String, String, String)
69110
* @param targetLanguage The language you want to translate into in ISO-639 format
70111
* @param text The text you actually want to translate
71112
* @return The translated text.
@@ -74,7 +115,7 @@ public static String translate(String text) throws IOException{
74115
public static String translate(String targetLanguage, String text) throws IOException{
75116
return translate("auto",targetLanguage, text);
76117
}
77-
118+
78119
/**
79120
* Translate text from sourceLanguage to targetLanguage
80121
* Specifying the sourceLanguage greatly improves accuracy over short Strings
@@ -85,9 +126,8 @@ public static String translate(String targetLanguage, String text) throws IOExce
85126
* @throws IOException if it cannot complete the request
86127
*/
87128
public static String translate(String sourceLanguage, String targetLanguage, String text) throws IOException{
88-
String encoded = URLEncoder.encode(text, "UTF-8"); //Encode
89-
//Generates URL
90-
URL url = new URL(GOOGLE_TRANSLATE_URL + "&sl=" + sourceLanguage + "&tl=" + targetLanguage + "&text=" + encoded);
129+
String urlText = generateURL(sourceLanguage, targetLanguage, text);
130+
URL url = new URL(urlText);//GOOGLE_TRANSLATE_URL + "&sl=" + sourceLanguage + "&tl=" + targetLanguage + "&text=" + encoded);
91131
String rawData = urlToText(url);//Gets text from Google
92132
if(rawData==null){
93133
return null;
@@ -98,7 +138,7 @@ public static String translate(String sourceLanguage, String targetLanguage, Str
98138
}
99139
return raw[1];//Returns the translation
100140
}
101-
141+
102142
/**
103143
* Converts a URL to Text
104144
* @param url that you want to generate a String from
@@ -136,7 +176,7 @@ private static String findLanguage(String rawData){
136176
if(dashDetected){
137177
int lastQuote = rawData.substring(i+2).indexOf('"');
138178
if(lastQuote>0)
139-
return rawData.substring(i+2,i+2+lastQuote);
179+
return rawData.substring(i+2,i+2+lastQuote);
140180
}
141181
else{
142182
String possible = rawData.substring(i+2,i+4);
@@ -148,7 +188,7 @@ private static String findLanguage(String rawData){
148188
}
149189
return null;
150190
}
151-
191+
152192
/**
153193
* Checks if all characters in text are letters.
154194
* @param text The text you want to determine the validity of.
@@ -162,6 +202,103 @@ private static boolean containsLettersOnly(String text){
162202
}
163203
return true;
164204
}
165-
166-
205+
206+
/*************************** Cryptography section ************************************************
207+
******************** Thank Dean1510 for the excellent code translation **************************/
208+
209+
210+
//TODO Possibly refactor code as utility class
211+
212+
/**
213+
* This function generates the b parameter for translation acting as the seed for the hashing algorithm.
214+
*/
215+
private static int generateB() {
216+
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy", Locale.US);
217+
218+
Date start;
219+
Date now;
220+
try {
221+
start = sdf.parse("01/01/1970");
222+
now = new Date();
223+
} catch (ParseException e) {
224+
return 402890;
225+
}
226+
long diff = now.getTime() - start.getTime();
227+
long hours = diff / (60 * 60 * 1000) % 24;
228+
long days = diff / (24 * 60 * 60 * 1000);
229+
return (int) (hours + days * 24);
230+
}
231+
232+
/**
233+
* An implementation of an unsigned right shift.
234+
* Necessary since Java does not have unsigned ints.
235+
* @param x The number you wish to shift.
236+
* @param bits The number of bytes you wish to shift.
237+
* @return The shifted number, unsigned.
238+
*/
239+
private static int shr32(int x, int bits) {
240+
if (x < 0) {
241+
long x_l = 0xffffffffl + x + 1;
242+
return (int) (x_l >> bits);
243+
}
244+
return x >> bits;
245+
}
246+
247+
private static int RL(int a, String b) {//I am not entirely sure what this magic does.
248+
for (int c = 0; c < b.length() - 2; c += 3) {
249+
int d = b.charAt(c + 2);
250+
d = d >= 65 ? d - 87 : d - 48;
251+
d = b.charAt(c + 1) == '+' ? shr32(a, d) : (a << d);
252+
a = b.charAt(c) == '+' ? (a + d & 0xFFFFFFFF) : a ^ d;
253+
}
254+
return a;
255+
}
256+
257+
/**
258+
* Generates the token needed for translation.
259+
* @param text The text you want to generate the token for.
260+
* @return The generated token as a string.
261+
*/
262+
private static String generateToken(String text) {
263+
int b = generateB();
264+
int e = 0;
265+
int f = 0;
266+
List<Integer> d = new ArrayList<Integer>();
267+
for (; f < text.length(); f++) {
268+
int g = text.charAt(f);
269+
if (0x80 > g) {
270+
d.add(e++, g);
271+
} else {
272+
if (0x800 > g) {
273+
d.add(e++, g >> 6 | 0xC0);
274+
} else {
275+
if (0xD800 == (g & 0xFC00) && f + 1 < text.length() &&
276+
0xDC00 == (text.charAt(f + 1) & 0xFC00)) {
277+
g = 0x10000 + ((g & 0x3FF) << 10) + (text.charAt(++f) & 0x3FF);
278+
d.add(e++, g >> 18 | 0xF0);
279+
d.add(e++, g >> 12 & 0x3F | 0x80);
280+
} else {
281+
d.add(e++, g >> 12 | 0xE0);
282+
d.add(e++, g >> 6 & 0x3F | 0x80);
283+
}
284+
}
285+
d.add(e++, g & 63 | 128);
286+
}
287+
}
288+
289+
int a_i = b;
290+
for (e = 0; e < d.size(); e++) {
291+
a_i += d.get(e);
292+
a_i = RL(a_i, "+-a^+6");
293+
}
294+
a_i = RL(a_i, "+-3^+b+-f");
295+
long a_l;
296+
if (0 > a_i) {
297+
a_l = 0x80000000l + (a_i & 0x7FFFFFFF);
298+
} else {
299+
a_l = a_i;
300+
}
301+
a_l %= Math.pow(10, 6);
302+
return String.format(Locale.US, "%d.%d", a_l, a_l ^ b);
303+
}
167304
}

0 commit comments

Comments
 (0)