// jDownloader - Downloadmanager // Copyright (C) 2008 JD-Team support@jdownloader.org // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. package jd.http; import java.util.ArrayList; import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Random; import org.appwork.utils.formatter.StringFormatter; public final class RandomUserAgent { private static class System { public String platform; public String osName; public String archs; public boolean inverseOrder; public boolean useIt; public System(final String platform, final String osName, final String archs, final boolean inverseOrder, final boolean useIt) { this.platform = platform; this.osName = osName; this.archs = archs; this.inverseOrder = inverseOrder; this.useIt = useIt; } } /** * Initial browser release date. Used for invalid randomDate() calls. */ private static final String[] releaseDate = { "2005", "11", "11" }; /** * Browser-Language */ private static java.util.List<String> langs = new ArrayList<String>(); /** * Firefox branch revision, version and release date triplet. They MUST * match! Release date in form of "YYYY.MM.DD[.HH]". As of Firefox version > * 3.0 buildHour is appended. Use ".xx" */ private static java.util.List<String> ffVersionInfos = new ArrayList<String>(); /** * Internet Explorer versions */ private static java.util.List<String> ieVersions = new ArrayList<String>(); /** * Windows Versions. E.g. NT 5.1 is Windows XP */ private static String winVersions = ""; /** * Windows: dotNet addon-strings, to make the user-agent more random */ private static java.util.List<String[]> winAddons = new ArrayList<String[]>(); /** * Linux: distribution addon-strings, to make the user-agent more random */ private static java.util.List<String> linuxAddons = new ArrayList<String>(); /** * Macintosh: version addon-strings, to make the user-agent more random */ private static java.util.List<String> macAddons = new ArrayList<String>(); /** * Information about the system: platform, OS, architecture */ private static java.util.List<System> system = new ArrayList<System>(); /** * Fill in the values (the "CONFIGURATION") */ static { /* Used only in generateIE */ RandomUserAgent.ieVersions.add("6.0"); RandomUserAgent.ieVersions.add("7.0"); RandomUserAgent.ieVersions.add("8.0"); /* Used in both generateIE and generateFF */ RandomUserAgent.winVersions = "NT 5.0|NT 5.1|NT 5.2|NT 6.0|NT 6.1"; RandomUserAgent.winAddons.add(new String[] { "", ".NET CLR 1.0.3705", ".NET CLR 1.1.4322" }); RandomUserAgent.winAddons.add(new String[] { "", ".NET CLR 2.0.40607", ".NET CLR 2.0.50727" }); RandomUserAgent.winAddons.add(new String[] { "", ".NET CLR 3.0.04506.648", ".NET CLR 3.0.4506.2152" }); RandomUserAgent.winAddons.add(new String[] { "", ".NET CLR 3.5.21022", ".NET CLR 3.5.30729" }); /* Used only in generateFF */ RandomUserAgent.langs.add("en"); RandomUserAgent.langs.add("en-US"); RandomUserAgent.langs.add("en-GB"); RandomUserAgent.ffVersionInfos.add("1.8|1.5|2005.11.11"); RandomUserAgent.ffVersionInfos.add("1.8.1|2.0|2006.10.10"); RandomUserAgent.ffVersionInfos.add("1.9|3.0|2008.05.29.xx"); RandomUserAgent.ffVersionInfos.add("1.9.0.5|3.0.5|2008.12.01.xx"); RandomUserAgent.ffVersionInfos.add("1.9.0.6|3.0.6|2009.01.19.xx"); RandomUserAgent.ffVersionInfos.add("1.9.0.7|3.0.7|2009.02.19.xx"); RandomUserAgent.ffVersionInfos.add("1.9.0.8|3.0.8|2009.03.26.xx"); RandomUserAgent.ffVersionInfos.add("1.9.0.9|3.0.9|2009.04.08.xx"); RandomUserAgent.ffVersionInfos.add("1.9.0.10|3.0.10|2009.04.23.xx"); RandomUserAgent.linuxAddons.add(" "); RandomUserAgent.linuxAddons.add("Ubuntu/8.04 (hardy)"); RandomUserAgent.linuxAddons.add("Ubuntu/8.10 (intrepid)"); // linuxAddons.add("Ubuntu/9.04 (jaunty)"); RandomUserAgent.linuxAddons.add("Fedora/3.0.6-1.fc10"); RandomUserAgent.linuxAddons.add("Fedora/3.0.10-1.fc10"); RandomUserAgent.linuxAddons.add("(Gentoo)"); RandomUserAgent.linuxAddons.add("SUSE/3.0-1.2"); RandomUserAgent.linuxAddons.add("SUSE/3.0-1.1"); RandomUserAgent.linuxAddons.add("Red Hat/3.0.5-1.el5_2"); RandomUserAgent.macAddons.add(""); RandomUserAgent.macAddons.add("Mach-O"); RandomUserAgent.macAddons.add("10.4"); RandomUserAgent.macAddons.add("10.5"); RandomUserAgent.macAddons.add("10.6"); RandomUserAgent.system.add(new System("Windows", "Windows", RandomUserAgent.winVersions, false, true)); RandomUserAgent.system.add(new System("X11", "Linux", "x86|x86_64|i586|i686", false, true)); RandomUserAgent.system.add(new System("Macintosh", "Mac OS X", "Intel|PPC|68K", true, true)); RandomUserAgent.system.add(new System("X11", "FreeBSD", "i386|amd64|sparc64|alpha", false, true)); RandomUserAgent.system.add(new System("X11", "OpenBSD", "i386|amd64|sparc64|alpha", false, true)); RandomUserAgent.system.add(new System("X11", "NetBSD", "i386|amd64|sparc64|alpha", false, true)); RandomUserAgent.system.add(new System("X11", "SunOS", "i86pc|sun4u", false, true)); } private static String dotNetString() { final Random rand = new Random(); String dotNet10 = "; " + RandomUserAgent.winAddons.get(0)[rand.nextInt(RandomUserAgent.winAddons.get(0).length)]; if (dotNet10.equalsIgnoreCase("; ")) { dotNet10 = ""; } String dotNet20 = "; " + RandomUserAgent.winAddons.get(1)[rand.nextInt(RandomUserAgent.winAddons.get(1).length)]; if (dotNet20.equalsIgnoreCase("; ")) { dotNet20 = ""; } String dotNet30 = ""; if (dotNet20.length() != 0) { dotNet30 = "; " + RandomUserAgent.winAddons.get(2)[rand.nextInt(RandomUserAgent.winAddons.get(2).length)]; } if (dotNet30.equalsIgnoreCase("; ")) { dotNet30 = ""; } String dotNet35 = ""; if (dotNet30.length() != 0) { dotNet35 = "; " + RandomUserAgent.winAddons.get(3)[rand.nextInt(RandomUserAgent.winAddons.get(3).length)]; } if (dotNet35.equalsIgnoreCase("; ")) { dotNet35 = ""; } return dotNet10 + dotNet20 + dotNet30 + dotNet35; } /** * The main user-agent string generator * * @return Random Firefox or Internet Explorer user-agent string */ public static String generate() { if (new Random().nextInt() % 2 == 0) { return RandomUserAgent.generateFF(); } else { return RandomUserAgent.generateIE(); } } /** * The Firefox user-agent string generator * * @return Random Firefox user-agent string */ public static String generateFF() { final Random rand = new Random(); String platform = ""; String osAndArch = ""; String winAddon = ""; String linuxAddon = " "; String macAddon = ""; /* Get system infos */ final int i = rand.nextInt(RandomUserAgent.system.size()); do { platform = RandomUserAgent.system.get(i).platform; final String osName = RandomUserAgent.system.get(i).osName; final String[] archs = RandomUserAgent.system.get(i).archs.split("\\|"); final String arch = archs[rand.nextInt(archs.length)]; if (!RandomUserAgent.system.get(i).inverseOrder) { osAndArch = osName + " " + arch; } else { osAndArch = arch + " " + osName; } } while (RandomUserAgent.system.get(i).useIt == false); /* Get optional strings */ if (RandomUserAgent.system.get(i).osName.equalsIgnoreCase("Windows")) { winAddon = RandomUserAgent.dotNetString(); if (winAddon.trim().length() > 0) { winAddon = (" (" + winAddon.trim() + ")").replace("(; ", "("); } } else if (RandomUserAgent.system.get(i).osName.equalsIgnoreCase("Linux")) { linuxAddon = RandomUserAgent.linuxAddons.get(rand.nextInt(RandomUserAgent.linuxAddons.size())); if (linuxAddon != " ") { linuxAddon = " " + linuxAddon.trim() + " "; } } else if (RandomUserAgent.system.get(i).osName.equalsIgnoreCase("Mac OS X")) { macAddon = RandomUserAgent.macAddons.get(rand.nextInt(RandomUserAgent.macAddons.size())); if (macAddon != "") { macAddon = " " + macAddon.trim(); } } /* Get Browser language */ final String lang = RandomUserAgent.langs.get(rand.nextInt(RandomUserAgent.langs.size())); /* Get Firefox branch revision, version and release date */ final String[] tmpFFVersionInfos = RandomUserAgent.ffVersionInfos.get(rand.nextInt(RandomUserAgent.ffVersionInfos.size())).split("\\|"); final String ffRev = tmpFFVersionInfos[0]; final String ffVersion = tmpFFVersionInfos[1]; final String[] ffReleaseDate = tmpFFVersionInfos[2].split("\\."); return "Mozilla/5.0 (" + platform + "; U; " + osAndArch + macAddon + "; " + lang + "; rv:" + ffRev + ") Gecko/" + RandomUserAgent.randomDate(ffReleaseDate) + linuxAddon + "Firefox/" + ffVersion + winAddon; } /** * The Internet Explorer user-agent string generator * * @return Random Internet Explorer user-agent string */ public static String generateIE() { final Random rand = new Random(); final String ieVersion = RandomUserAgent.ieVersions.get(rand.nextInt(RandomUserAgent.ieVersions.size())); final String winVersion = RandomUserAgent.winVersions.split("\\|")[rand.nextInt(RandomUserAgent.winVersions.split("\\|").length)]; String trident = ""; if (ieVersion.equalsIgnoreCase("8.0")) { trident = "; Trident/4.0"; } return "Mozilla/4.0 (compatible; MSIE " + ieVersion + "; Windows " + winVersion + trident + RandomUserAgent.dotNetString() + ")"; } /** * Generates a random date in form of "YYYYMMDD[HH]" between releaseDate and * the current date * * @return random date */ private static String randomDate(final String[] releaseDate) { String returnDate = RandomUserAgent.releaseDate[0] + RandomUserAgent.releaseDate[1] + RandomUserAgent.releaseDate[2]; if (releaseDate == null || releaseDate.length < 3 || releaseDate.length > 4) { return returnDate; } final Calendar rCal = new GregorianCalendar(Integer.parseInt(releaseDate[0]), Integer.parseInt(releaseDate[1]) - 1, Integer.parseInt(releaseDate[2])); final long rTime = rCal.getTimeInMillis(); final long cTime = new GregorianCalendar().getTimeInMillis(); final Random rand = new Random(); int temp = (int) ((cTime - rTime) / (60 * 1000)) + (int) (rTime / (60 * 1000)); if (temp < 0) { temp = -temp; } final long randTime = rand.nextInt(temp); rCal.setTimeInMillis(randTime * 60 * 1000); final int year = rCal.get(Calendar.YEAR); final String month = StringFormatter.fillString(rCal.get(Calendar.MONTH) + 1 + "", "0", "", 2); final String day = StringFormatter.fillString(rCal.get(Calendar.DAY_OF_MONTH) + "", "0", "", 2); String hour = ""; if (releaseDate.length == 4) { hour = StringFormatter.fillString(rand.nextInt(24) + "", "0", "", 2); } returnDate = "" + year + month + day + hour; return returnDate; } /** * Don't let anyone instantiate this class. */ private RandomUserAgent() { } }