Advertisement
Guest User

Untitled

a guest
Nov 3rd, 2014
210
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 26.69 KB | None | 0 0
  1. package com.jagex.runescape;
  2.  
  3. final class Censor {
  4.  
  5.     public static void load(Archive archive) {
  6.         Stream fragmentsEnc = new Stream(
  7.                 archive.getFile("fragmentsenc.txt"));
  8.         Stream badEnc = new Stream(archive.getFile("badenc.txt"));
  9.         Stream domainEnc = new Stream(archive.getFile("domainenc.txt"));
  10.         Stream topLevelDomainList = new Stream(
  11.                 archive.getFile("tldlist.txt"));
  12.         loadDictionaries(fragmentsEnc, badEnc, domainEnc, topLevelDomainList);
  13.     }
  14.  
  15.     private static void loadDictionaries(Stream fragment, Stream bad,
  16.             Stream domain, Stream topLevelDomain) {
  17.         loadBadEnc(bad);
  18.         loadDomainEnc(domain);
  19.         loadFragmentsEnc(fragment);
  20.         loadTopLevelDomainList(topLevelDomain);
  21.     }
  22.  
  23.     private static void loadTopLevelDomainList(Stream stream) {
  24.         int length = stream.getInt();
  25.         topLevelDomains = new char[length][];
  26.         topLevelDomainType = new int[length];
  27.         for (int index = 0; index < length; index++) {
  28.             topLevelDomainType[index] = stream.getUnsignedByte();
  29.             char topLevelDomain[] = new char[stream.getUnsignedByte()];
  30.             for (int d = 0; d < topLevelDomain.length; d++)
  31.                 topLevelDomain[d] = (char) stream.getUnsignedByte();
  32.  
  33.             topLevelDomains[index] = topLevelDomain;
  34.         }
  35.     }
  36.  
  37.     private static void loadBadEnc(Stream stream) {
  38.         int length = stream.getInt();
  39.         badWords = new char[length][];
  40.         badBytes = new byte[length][][];
  41.         loadBadWords(stream, badWords, badBytes);
  42.     }
  43.  
  44.     private static void loadDomainEnc(Stream stream) {
  45.         int length = stream.getInt();
  46.         domains = new char[length][];
  47.         loadDomains(domains, stream);
  48.     }
  49.  
  50.     private static void loadFragmentsEnc(Stream stream) {
  51.         fragments = new int[stream.getInt()];
  52.         for (int i = 0; i < fragments.length; i++)
  53.             fragments[i] = stream.getUnsignedLEShort();
  54.     }
  55.  
  56.     private static void loadBadWords(Stream stream, char badWords[][],
  57.             byte badBytes[][][]) {
  58.         for (int w = 0; w < badWords.length; w++) {
  59.             char badWord[] = new char[stream.getUnsignedByte()];
  60.             for (int c = 0; c < badWord.length; c++)
  61.                 badWord[c] = (char) stream.getUnsignedByte();
  62.  
  63.             badWords[w] = badWord;
  64.             byte badByte[][] = new byte[stream.getUnsignedByte()][2];
  65.             for (int b = 0; b < badByte.length; b++) {
  66.                 badByte[b][0] = (byte) stream.getUnsignedByte();
  67.                 badByte[b][1] = (byte) stream.getUnsignedByte();
  68.             }
  69.  
  70.             if (badByte.length > 0)
  71.                 badBytes[w] = badByte;
  72.         }
  73.  
  74.     }
  75.  
  76.     private static void loadDomains(char domains[][], Stream stream) {
  77.         for (int d = 0; d < domains.length; d++) {
  78.             char domain[] = new char[stream.getUnsignedByte()];
  79.             for (int c = 0; c < domain.length; c++)
  80.                 domain[c] = (char) stream.getUnsignedByte();
  81.             domains[d] = domain;
  82.         }
  83.     }
  84.  
  85.     private static void formatLegalCharacters(char characters[]) {
  86.         int character = 0;
  87.         for (int c = 0; c < characters.length; c++) {
  88.             if (isLegalCharacter(characters[c]))
  89.                 characters[character] = characters[c];
  90.             else
  91.                 characters[character] = ' ';
  92.             if (character == 0 || characters[character] != ' '
  93.                     || characters[character - 1] != ' ')
  94.                 character++;
  95.         }
  96.         for (int c = character; c < characters.length; c++)
  97.             characters[c] = ' ';
  98.     }
  99.  
  100.     private static boolean isLegalCharacter(char c) {
  101.         return c >= ' ' && c <= '\177' || c == ' ' || c == '\n' || c == '\t'
  102.                 || c == '\243' || c == '\u20AC';
  103.     }
  104.  
  105.     public static String censorString(String string) {
  106.         char stringLetters[] = string.toCharArray();
  107.         formatLegalCharacters(stringLetters);
  108.         String trimmedString = (new String(stringLetters)).trim();
  109.         stringLetters = trimmedString.toLowerCase().toCharArray();
  110.         String lowercaseTrimmedString = trimmedString.toLowerCase();
  111.         removeTLDs(stringLetters);
  112.         censorBadWords(stringLetters);
  113.         removeEmails(stringLetters);
  114.         censorLongNumbers(stringLetters);
  115.         for (int e = 0; e < exceptions.length; e++) {
  116.             for (int c = -1; (c = lowercaseTrimmedString.indexOf(exceptions[e],
  117.                     c + 1)) != -1;) {
  118.                 char exception[] = exceptions[e].toCharArray();
  119.                 System.arraycopy(exception, 0, stringLetters, c,
  120.                         exception.length);
  121.             }
  122.         }
  123.         transferCapitals(trimmedString.toCharArray(), stringLetters);
  124.         fixCases(stringLetters);
  125.         return (new String(stringLetters)).trim();
  126.     }
  127.  
  128.     private static void transferCapitals(char input[], char output[]) {
  129.         for (int c = 0; c < input.length; c++)
  130.             if (output[c] != '*' && isUpperCaseLetter(input[c]))
  131.                 output[c] = input[c];
  132.     }
  133.  
  134.     private static void fixCases(char input[]) {
  135.         boolean skipToNextUppercase = true;
  136.         for (int pos = 0; pos < input.length; pos++) {
  137.             char c = input[pos];
  138.             if (isLetter(c)) {
  139.                 if (skipToNextUppercase) {
  140.                     if (isLowerCaseLetter(c))
  141.                         skipToNextUppercase = false;
  142.                 } else if (isUpperCaseLetter(c))
  143.                     input[pos] = (char) ((c + 97) - 65);
  144.             } else {
  145.                 skipToNextUppercase = true;
  146.             }
  147.         }
  148.     }
  149.  
  150.     private static void censorBadWords(char input[]) {
  151.         for (int pass = 0; pass < 2; pass++) {
  152.             for (int bad = badWords.length - 1; bad >= 0; bad--)
  153.                 censorPart(badBytes[bad], input, badWords[bad]);
  154.         }
  155.     }
  156.  
  157.     private static void removeEmails(char input[]) {
  158.         char inputAtStripped[] = input.clone();
  159.         char charactersAt[] = { '(', 'a', ')' };
  160.         censorPart(null, inputAtStripped, charactersAt);
  161.         char inputDotStripped[] = input.clone();
  162.         char charactersDot[] = { 'd', 'o', 't' };
  163.         censorPart(null, inputDotStripped, charactersDot);
  164.         for (int d = domains.length - 1; d >= 0; d--)
  165.             removeEmail(input, domains[d], inputDotStripped, inputAtStripped);
  166.     }
  167.  
  168.     private static void removeEmail(char inputRaw[], char domain[],
  169.             char inputDotStripped[], char inputAtStripped[]) {
  170.         if (domain.length > inputRaw.length)
  171.             return;
  172.         int increment;
  173.         for (int start = 0; start <= inputRaw.length - domain.length; start += increment) {
  174.             int end = start;
  175.             int charactersFound = 0;
  176.             increment = 1;
  177.             while (end < inputRaw.length) {
  178.                 int incrementEnd;
  179.                 char characterEnd = inputRaw[end];
  180.                 char characterNext = '\0';
  181.                 if (end + 1 < inputRaw.length)
  182.                     characterNext = inputRaw[end + 1];
  183.                 if (charactersFound < domain.length
  184.                         && (incrementEnd = basicLeetspeekCheck(characterEnd,
  185.                                 domain[charactersFound], characterNext)) > 0) {
  186.                     end += incrementEnd;
  187.                     charactersFound++;
  188.                     continue;
  189.                 }
  190.                 if (charactersFound == 0)
  191.                     break;
  192.                 if ((incrementEnd = basicLeetspeekCheck(characterEnd,
  193.                         domain[charactersFound - 1], characterNext)) > 0) {
  194.                     end += incrementEnd;
  195.                     if (charactersFound == 1)
  196.                         increment++;
  197.                     continue;
  198.                 }
  199.                 if (charactersFound >= domain.length
  200.                         || !isNotAlphanumeric(characterEnd))
  201.                     break;
  202.                 end++;
  203.             }
  204.             if (charactersFound >= domain.length) {
  205.                 boolean censor = false;
  206.                 int atSignBeforeDomain = atSignBeforeDomain(inputRaw,
  207.                         inputAtStripped, start);
  208.                 int dotAfterDomain = dotAfterDomain(inputDotStripped, end - 1,
  209.                         inputRaw);
  210.                 if (atSignBeforeDomain > 2 || dotAfterDomain > 2)
  211.                     censor = true;
  212.                 if (censor) {
  213.                     for (int c = start; c < end; c++)
  214.                         inputRaw[c] = '*';
  215.                 }
  216.             }
  217.         }
  218.     }
  219.  
  220.     private static int atSignBeforeDomain(char input[], char inputAtStripped[],
  221.             int start) {
  222.         if (start == 0)
  223.             return 2;
  224.         for (int c = start - 1; c >= 0; c--) {
  225.             if (!isNotAlphanumeric(input[c]))
  226.                 break;
  227.             if (input[c] == '@')
  228.                 return 3;
  229.         }
  230.  
  231.         int censorCount = 0;
  232.         for (int c = start - 1; c >= 0; c--) {
  233.             if (!isNotAlphanumeric(inputAtStripped[c]))
  234.                 break;
  235.             if (inputAtStripped[c] == '*')
  236.                 censorCount++;
  237.         }
  238.  
  239.         if (censorCount >= 3)
  240.             return 4;
  241.         return !isNotAlphanumeric(input[start - 1]) ? 0 : 1;
  242.     }
  243.  
  244.     private static int dotAfterDomain(char inputDotStripped[], int end,
  245.             char input[]) {
  246.         if (end + 1 == input.length)
  247.             return 2;
  248.         for (int c = end + 1; c < input.length; c++) {
  249.             if (!isNotAlphanumeric(input[c]))
  250.                 break;
  251.             if (input[c] == '.' || input[c] == ',')
  252.                 return 3;
  253.         }
  254.         int censorCount = 0;
  255.         for (int c = end + 1; c < input.length; c++) {
  256.             if (!isNotAlphanumeric(inputDotStripped[c]))
  257.                 break;
  258.             if (inputDotStripped[c] == '*')
  259.                 censorCount++;
  260.         }
  261.  
  262.         if (censorCount >= 3)
  263.             return 4;
  264.         return !isNotAlphanumeric(input[end + 1]) ? 0 : 1;
  265.     }
  266.  
  267.     private static void removeTLDs(char input[]) {
  268.         char dotStrippedInput[] = input.clone();
  269.         char dotCharacters[] = { 'd', 'o', 't' };
  270.         censorPart(null, dotStrippedInput, dotCharacters);
  271.         char slashStrippedInput[] = input.clone();
  272.         char slashCharacters[] = { 's', 'l', 'a', 's', 'h' };
  273.         censorPart(null, slashStrippedInput, slashCharacters);
  274.         for (int domain = 0; domain < topLevelDomains.length; domain++)
  275.             removeTLD(slashStrippedInput, topLevelDomains[domain],
  276.                     topLevelDomainType[domain], dotStrippedInput, input);
  277.  
  278.     }
  279.  
  280.     private static void removeTLD(char inputSlashStripped[], char tld[],
  281.             int tldType, char inputDotStripped[], char inputRaw[]) {
  282.         if (tld.length > inputRaw.length)
  283.             return;
  284.         int increment;
  285.         for (int pos = 0; pos <= inputRaw.length - tld.length; pos += increment) {
  286.             int end = pos;
  287.             int charactersFound = 0;
  288.             increment = 1;
  289.             while (end < inputRaw.length) {
  290.                 int incrementEnd;
  291.                 char characterEnd = inputRaw[end];
  292.                 char characterNext = '\0';
  293.                 if (end + 1 < inputRaw.length)
  294.                     characterNext = inputRaw[end + 1];
  295.                 if (charactersFound < tld.length
  296.                         && (incrementEnd = basicLeetspeekCheck(characterEnd,
  297.                                 tld[charactersFound], characterNext)) > 0) {
  298.                     end += incrementEnd;
  299.                     charactersFound++;
  300.                     continue;
  301.                 }
  302.                 if (charactersFound == 0)
  303.                     break;
  304.                 if ((incrementEnd = basicLeetspeekCheck(characterEnd,
  305.                         tld[charactersFound - 1], characterNext)) > 0) {
  306.                     end += incrementEnd;
  307.                     if (charactersFound == 1)
  308.                         increment++;
  309.                     continue;
  310.                 }
  311.                 if (charactersFound >= tld.length
  312.                         || !isNotAlphanumeric(characterEnd))
  313.                     break;
  314.                 end++;
  315.             }
  316.             if (charactersFound >= tld.length) {
  317.                 boolean censor = false;
  318.                 int dotBeforeTLD = dotBeforeTLD(inputRaw, pos, inputDotStripped);
  319.                 int slashAfterTLD = slashAfterTLD(inputRaw, inputSlashStripped,
  320.                         end - 1);
  321.                 if (tldType == 1 && dotBeforeTLD > 0 && slashAfterTLD > 0)
  322.                     censor = true;
  323.                 if (tldType == 2
  324.                         && (dotBeforeTLD > 2 && slashAfterTLD > 0 || dotBeforeTLD > 0
  325.                                 && slashAfterTLD > 2))
  326.                     censor = true;
  327.                 if (tldType == 3 && dotBeforeTLD > 0 && slashAfterTLD > 2)
  328.                     censor = true;
  329.                 // boolean _tmp = tldType == 3 && dotBeforeTLD > 2 &&
  330.                 // slashAfterTLD > 0; // unused
  331.                 if (censor) {
  332.                     int censorStart = pos;
  333.                     int censorEnd = end - 1;
  334.                     if (dotBeforeTLD > 2) {
  335.                         if (dotBeforeTLD == 4) {
  336.                             boolean breakUncensored = false;
  337.                             for (int c = censorStart - 1; c >= 0; c--)
  338.                                 if (breakUncensored) {
  339.                                     if (inputDotStripped[c] != '*')
  340.                                         break;
  341.                                     censorStart = c;
  342.                                 } else if (inputDotStripped[c] == '*') {
  343.                                     censorStart = c;
  344.                                     breakUncensored = true;
  345.                                 }
  346.  
  347.                         }
  348.                         boolean breakNonAlphanumeric = false;
  349.                         for (int c = censorStart - 1; c >= 0; c--)
  350.                             if (breakNonAlphanumeric) {
  351.                                 if (isNotAlphanumeric(inputRaw[c]))
  352.                                     break;
  353.                                 censorStart = c;
  354.                             } else if (!isNotAlphanumeric(inputRaw[c])) {
  355.                                 breakNonAlphanumeric = true;
  356.                                 censorStart = c;
  357.                             }
  358.  
  359.                     }
  360.                     if (slashAfterTLD > 2) {
  361.                         if (slashAfterTLD == 4) {
  362.                             boolean breakUncensored = false;
  363.                             for (int c = censorEnd + 1; c < inputRaw.length; c++)
  364.                                 if (breakUncensored) {
  365.                                     if (inputSlashStripped[c] != '*')
  366.                                         break;
  367.                                     censorEnd = c;
  368.                                 } else if (inputSlashStripped[c] == '*') {
  369.                                     censorEnd = c;
  370.                                     breakUncensored = true;
  371.                                 }
  372.  
  373.                         }
  374.                         boolean breakNonAlphanumeric = false;
  375.                         for (int c = censorEnd + 1; c < inputRaw.length; c++)
  376.                             if (breakNonAlphanumeric) {
  377.                                 if (isNotAlphanumeric(inputRaw[c]))
  378.                                     break;
  379.                                 censorEnd = c;
  380.                             } else if (!isNotAlphanumeric(inputRaw[c])) {
  381.                                 breakNonAlphanumeric = true;
  382.                                 censorEnd = c;
  383.                             }
  384.  
  385.                     }
  386.                     for (int c = censorStart; c <= censorEnd; c++)
  387.                         inputRaw[c] = '*';
  388.  
  389.                 }
  390.             }
  391.         }
  392.     }
  393.  
  394.     private static int dotBeforeTLD(char inputRaw[], int start,
  395.             char inputStripped[]) {
  396.         if (start == 0)
  397.             return 2;
  398.         for (int c = start - 1; c >= 0; c--) {
  399.             if (!isNotAlphanumeric(inputRaw[c]))
  400.                 break;
  401.             if (inputRaw[c] == ',' || inputRaw[c] == '.')
  402.                 return 3;
  403.         }
  404.  
  405.         int asteriskCount = 0;
  406.         for (int c = start - 1; c >= 0; c--) {
  407.             if (!isNotAlphanumeric(inputStripped[c]))
  408.                 break;
  409.             if (inputStripped[c] == '*')
  410.                 asteriskCount++;
  411.         }
  412.         if (asteriskCount >= 3)
  413.             return 4;
  414.         return !isNotAlphanumeric(inputRaw[start - 1]) ? 0 : 1;
  415.     }
  416.  
  417.     private static int slashAfterTLD(char inputRaw[], char inputSlashRemoved[],
  418.             int start) {
  419.         if (start + 1 == inputRaw.length)
  420.             return 2;
  421.         for (int c = start + 1; c < inputRaw.length; c++) {
  422.             if (!isNotAlphanumeric(inputRaw[c]))
  423.                 break;
  424.             if (inputRaw[c] == '\\' || inputRaw[c] == '/')
  425.                 return 3;
  426.         }
  427.  
  428.         int asteriskCount = 0;
  429.         for (int c = start + 1; c < inputRaw.length; c++) {
  430.             if (!isNotAlphanumeric(inputSlashRemoved[c]))
  431.                 break;
  432.             if (inputSlashRemoved[c] == '*')
  433.                 asteriskCount++;
  434.         }
  435.  
  436.         if (asteriskCount >= 5)
  437.             return 4;
  438.         return !isNotAlphanumeric(inputRaw[start + 1]) ? 0 : 1;
  439.     }
  440.  
  441.     private static void censorPart(byte bytes[][], char input[], char search[]) {
  442.         if (search.length > input.length)
  443.             return;
  444.         // boolean flag = true; // unused
  445.         int moreDigitsThanLetters;
  446.         for (int start = 0; start <= input.length - search.length; start += moreDigitsThanLetters) {
  447.             int end = start;
  448.             int charactersFound = 0;
  449.             int counter = 0;
  450.             moreDigitsThanLetters = 1;
  451.             boolean notAlphanumericOrApostrophe = false;
  452.             boolean digitUpcoming = false;
  453.             boolean digitEnd = false;
  454.             while (end < input.length && (!digitUpcoming || !digitEnd)) {
  455.                 int incrementEnd;
  456.                 char characterEnd = input[end];
  457.                 char characterNext = '\0';
  458.                 if (end + 1 < input.length)
  459.                     characterNext = input[end + 1];
  460.                 if (charactersFound < search.length
  461.                         && (incrementEnd = advancedLeetspeekCheck(
  462.                                 characterNext, characterEnd,
  463.                                 search[charactersFound])) > 0) {
  464.                     if (incrementEnd == 1 && isDigit(characterEnd))
  465.                         digitUpcoming = true;
  466.                     if (incrementEnd == 2
  467.                             && (isDigit(characterEnd) || isDigit(characterNext)))
  468.                         digitUpcoming = true;
  469.                     end += incrementEnd;
  470.                     charactersFound++;
  471.                     continue;
  472.                 }
  473.                 if (charactersFound == 0)
  474.                     break;
  475.                 if ((incrementEnd = advancedLeetspeekCheck(characterNext,
  476.                         characterEnd, search[charactersFound - 1])) > 0) {
  477.                     end += incrementEnd;
  478.                     if (charactersFound == 1)
  479.                         moreDigitsThanLetters++;
  480.                     continue;
  481.                 }
  482.                 if (charactersFound >= search.length
  483.                         || !isDigitOrSymbol(characterEnd))
  484.                     break;
  485.                 if (isNotAlphanumeric(characterEnd) && characterEnd != '\'')
  486.                     notAlphanumericOrApostrophe = true;
  487.                 if (isDigit(characterEnd))
  488.                     digitEnd = true;
  489.                 end++;
  490.                 if ((++counter * 100) / (end - start) > 90)
  491.                     break;
  492.             }
  493.             if (charactersFound >= search.length
  494.                     && (!digitUpcoming || !digitEnd)) {
  495.                 boolean censor = true;
  496.                 if (!notAlphanumericOrApostrophe) {
  497.                     char characterBeforeStart = ' ';
  498.                     if (start - 1 >= 0)
  499.                         characterBeforeStart = input[start - 1];
  500.                     char characterAtEnd = ' ';
  501.                     if (end < input.length)
  502.                         characterAtEnd = input[end];
  503.                     byte codeStart = getCharCode(characterBeforeStart);
  504.                     byte codeEnd = getCharCode(characterAtEnd);
  505.                     if (bytes != null
  506.                             && charCodesCensorable(codeStart, bytes, codeEnd))
  507.                         censor = false;
  508.                 } else {
  509.                     boolean invalidBeforeStart = false;
  510.                     boolean invalidAtEnd = false;
  511.                     if (start - 1 < 0 || isNotAlphanumeric(input[start - 1])
  512.                             && input[start - 1] != '\'')
  513.                         invalidBeforeStart = true;
  514.                     if (end >= input.length || isNotAlphanumeric(input[end])
  515.                             && input[end] != '\'')
  516.                         invalidAtEnd = true;
  517.                     if (!invalidBeforeStart || !invalidAtEnd) {
  518.                         boolean valid = false;
  519.                         int c = start - 2;
  520.                         if (invalidBeforeStart)
  521.                             c = start;
  522.                         for (; !valid && c < end; c++)
  523.                             if (c >= 0
  524.                                     && (!isNotAlphanumeric(input[c]) || input[c] == '\'')) {
  525.                                 char chars[] = new char[3];
  526.                                 int _c;
  527.                                 for (_c = 0; _c < 3; _c++) {
  528.                                     if (c + _c >= input.length
  529.                                             || isNotAlphanumeric(input[c + _c])
  530.                                             && input[c + _c] != '\'')
  531.                                         break;
  532.                                     chars[_c] = input[c + _c];
  533.                                 }
  534.  
  535.                                 boolean testsPassed = true;
  536.                                 if (_c == 0)
  537.                                     testsPassed = false;
  538.                                 if (_c < 3
  539.                                         && c - 1 >= 0
  540.                                         && (!isNotAlphanumeric(input[c - 1]) || input[c - 1] == '\''))
  541.                                     testsPassed = false;
  542.                                 if (testsPassed
  543.                                         && !charactersMatchFragment(chars))
  544.                                     valid = true;
  545.                             }
  546.  
  547.                         if (!valid)
  548.                             censor = false;
  549.                     }
  550.                 }
  551.                 if (censor) {
  552.                     int countDigits = 0;
  553.                     int countLetters = 0;
  554.                     int positionLastLetter = -1;
  555.                     for (int c = start; c < end; c++)
  556.                         if (isDigit(input[c]))
  557.                             countDigits++;
  558.                         else if (isLetter(input[c])) {
  559.                             countLetters++;
  560.                             positionLastLetter = c;
  561.                         }
  562.  
  563.                     if (positionLastLetter > -1)
  564.                         countDigits -= end - 1 - positionLastLetter;
  565.                     if (countDigits <= countLetters) {
  566.                         for (int c = start; c < end; c++)
  567.                             input[c] = '*';
  568.                     } else {
  569.                         moreDigitsThanLetters = 1;
  570.                     }
  571.                 }
  572.             }
  573.         }
  574.     }
  575.  
  576.     private static boolean charCodesCensorable(byte codeBeforeStart,
  577.             byte bytes[][], byte codeAtEnd) {
  578.         int pos = 0;
  579.         if (bytes[pos][0] == codeBeforeStart && bytes[pos][1] == codeAtEnd)
  580.             return true;
  581.         int length = bytes.length - 1;
  582.         if (bytes[length][0] == codeBeforeStart
  583.                 && bytes[length][1] == codeAtEnd)
  584.             return true;
  585.         do {
  586.             int newPos = (pos + length) / 2;
  587.             if (bytes[newPos][0] == codeBeforeStart
  588.                     && bytes[newPos][1] == codeAtEnd)
  589.                 return true;
  590.             if (codeBeforeStart < bytes[newPos][0]
  591.                     || codeBeforeStart == bytes[newPos][0]
  592.                     && codeAtEnd < bytes[newPos][1])
  593.                 length = newPos;
  594.             else
  595.                 pos = newPos;
  596.         } while (pos != length && pos + 1 != length);
  597.         return false;
  598.     }
  599.  
  600.     private static int basicLeetspeekCheck(char firstChararacter, char find,
  601.             char secondCharacter) {
  602.         if (find == firstChararacter)
  603.             return 1;
  604.         if (find == 'o' && firstChararacter == '0')
  605.             return 1;
  606.         if (find == 'o' && firstChararacter == '(' && secondCharacter == ')')
  607.             return 2;
  608.         if (find == 'c'
  609.                 && (firstChararacter == '(' || firstChararacter == '<' || firstChararacter == '['))
  610.             return 1;
  611.         if (find == 'e' && firstChararacter == '\u20AC')
  612.             return 1;
  613.         if (find == 's' && firstChararacter == '$')
  614.             return 1;
  615.         return find != 'l' || firstChararacter != 'i' ? 0 : 1;
  616.     }
  617.  
  618.     private static int advancedLeetspeekCheck(char secondCharacter,
  619.             char firstCharacter, char find) {
  620.         if (find == firstCharacter)
  621.             return 1;
  622.         if (find >= 'a' && find <= 'm') {
  623.             if (find == 'a') {
  624.                 if (firstCharacter == '4' || firstCharacter == '@'
  625.                         || firstCharacter == '^')
  626.                     return 1;
  627.                 return firstCharacter != '/' || secondCharacter != '\\' ? 0 : 2;
  628.             }
  629.             if (find == 'b') {
  630.                 if (firstCharacter == '6' || firstCharacter == '8')
  631.                     return 1;
  632.                 return (firstCharacter != '1' || secondCharacter != '3')
  633.                         && (firstCharacter != 'i' || secondCharacter != '3') ? 0
  634.                         : 2;
  635.             }
  636.             if (find == 'c')
  637.                 return firstCharacter != '(' && firstCharacter != '<'
  638.                         && firstCharacter != '{' && firstCharacter != '[' ? 0
  639.                         : 1;
  640.             if (find == 'd')
  641.                 return (firstCharacter != '[' || secondCharacter != ')')
  642.                         && (firstCharacter != 'i' || secondCharacter != ')') ? 0
  643.                         : 2;
  644.             if (find == 'e')
  645.                 return firstCharacter != '3' && firstCharacter != '\u20AC' ? 0
  646.                         : 1;
  647.             if (find == 'f') {
  648.                 if (firstCharacter == 'p' && secondCharacter == 'h')
  649.                     return 2;
  650.                 return firstCharacter != '\243' ? 0 : 1;
  651.             }
  652.             if (find == 'g')
  653.                 return firstCharacter != '9' && firstCharacter != '6'
  654.                         && firstCharacter != 'q' ? 0 : 1;
  655.             if (find == 'h')
  656.                 return firstCharacter != '#' ? 0 : 1;
  657.             if (find == 'i')
  658.                 return firstCharacter != 'y' && firstCharacter != 'l'
  659.                         && firstCharacter != 'j' && firstCharacter != '1'
  660.                         && firstCharacter != '!' && firstCharacter != ':'
  661.                         && firstCharacter != ';' && firstCharacter != '|' ? 0
  662.                         : 1;
  663.             if (find == 'j')
  664.                 return 0;
  665.             if (find == 'k')
  666.                 return 0;
  667.             if (find == 'l')
  668.                 return firstCharacter != '1' && firstCharacter != '|'
  669.                         && firstCharacter != 'i' ? 0 : 1;
  670.             if (find == 'm')
  671.                 return 0;
  672.         }
  673.         if (find >= 'n' && find <= 'z') {
  674.             if (find == 'n')
  675.                 return 0;
  676.             if (find == 'o') {
  677.                 if (firstCharacter == '0' || firstCharacter == '*')
  678.                     return 1;
  679.                 return (firstCharacter != '(' || secondCharacter != ')')
  680.                         && (firstCharacter != '[' || secondCharacter != ']')
  681.                         && (firstCharacter != '{' || secondCharacter != '}')
  682.                         && (firstCharacter != '<' || secondCharacter != '>') ? 0
  683.                         : 2;
  684.             }
  685.             if (find == 'p')
  686.                 return 0;
  687.             if (find == 'q')
  688.                 return 0;
  689.             if (find == 'r')
  690.                 return 0;
  691.             if (find == 's')
  692.                 return firstCharacter != '5' && firstCharacter != 'z'
  693.                         && firstCharacter != '$' && firstCharacter != '2' ? 0
  694.                         : 1;
  695.             if (find == 't')
  696.                 return firstCharacter != '7' && firstCharacter != '+' ? 0 : 1;
  697.             if (find == 'u') {
  698.                 if (firstCharacter == 'v')
  699.                     return 1;
  700.                 return (firstCharacter != '\\' || secondCharacter != '/')
  701.                         && (firstCharacter != '\\' || secondCharacter != '|')
  702.                         && (firstCharacter != '|' || secondCharacter != '/') ? 0
  703.                         : 2;
  704.             }
  705.             if (find == 'v')
  706.                 return (firstCharacter != '\\' || secondCharacter != '/')
  707.                         && (firstCharacter != '\\' || secondCharacter != '|')
  708.                         && (firstCharacter != '|' || secondCharacter != '/') ? 0
  709.                         : 2;
  710.             if (find == 'w')
  711.                 return firstCharacter != 'v' || secondCharacter != 'v' ? 0 : 2;
  712.             if (find == 'x')
  713.                 return (firstCharacter != ')' || secondCharacter != '(')
  714.                         && (firstCharacter != '}' || secondCharacter != '{')
  715.                         && (firstCharacter != ']' || secondCharacter != '[')
  716.                         && (firstCharacter != '>' || secondCharacter != '<') ? 0
  717.                         : 2;
  718.             if (find == 'y')
  719.                 return 0;
  720.             if (find == 'z')
  721.                 return 0;
  722.         }
  723.         if (find >= '0' && find <= '9') {
  724.             if (find == '0') {
  725.                 if (firstCharacter == 'o' || firstCharacter == 'O')
  726.                     return 1;
  727.                 return (firstCharacter != '(' || secondCharacter != ')')
  728.                         && (firstCharacter != '{' || secondCharacter != '}')
  729.                         && (firstCharacter != '[' || secondCharacter != ']') ? 0
  730.                         : 2;
  731.             }
  732.             if (find == '1')
  733.                 return firstCharacter != 'l' ? 0 : 1;
  734.             else
  735.                 return 0;
  736.         }
  737.         if (find == ',')
  738.             return firstCharacter != '.' ? 0 : 1;
  739.         if (find == '.')
  740.             return firstCharacter != ',' ? 0 : 1;
  741.         if (find == '!')
  742.             return firstCharacter != 'i' ? 0 : 1;
  743.         else
  744.             return 0;
  745.     }
  746.  
  747.     private static byte getCharCode(char c) {
  748.         if (c >= 'a' && c <= 'z')
  749.             return (byte) ((c - 97) + 1);
  750.         if (c == '\'')
  751.             return 28;
  752.         if (c >= '0' && c <= '9')
  753.             return (byte) ((c - 48) + 29);
  754.         else
  755.             return 27;
  756.     }
  757.  
  758.     private static void censorLongNumbers(char input[]) {
  759.         int nextDigit;
  760.         int nextNonDigit = 0;
  761.         int invalidFound = 0;
  762.         int start = 0;
  763.         while ((nextDigit = getFirstDigitPosition(input, nextNonDigit)) != -1) {
  764.             boolean charactersBeforeNextDigit = false;
  765.             for (int c = nextNonDigit; c >= 0 && c < nextDigit
  766.                     && !charactersBeforeNextDigit; c++)
  767.                 if (!isNotAlphanumeric(input[c]) && !isDigitOrSymbol(input[c]))
  768.                     charactersBeforeNextDigit = true;
  769.  
  770.             if (charactersBeforeNextDigit)
  771.                 invalidFound = 0;
  772.             if (invalidFound == 0)
  773.                 start = nextDigit;
  774.             nextNonDigit = getFirstNonDigitPosition(input, nextDigit);
  775.             int value = 0;
  776.             for (int c = nextDigit; c < nextNonDigit; c++)
  777.                 value = (value * 10 + input[c]) - 48;
  778.  
  779.             if (value > 255 || nextNonDigit - nextDigit > 8)
  780.                 invalidFound = 0;
  781.             else
  782.                 invalidFound++;
  783.             if (invalidFound == 4) {
  784.                 for (int c = start; c < nextNonDigit; c++)
  785.                     input[c] = '*';
  786.  
  787.                 invalidFound = 0;
  788.             }
  789.         }
  790.     }
  791.  
  792.     private static int getFirstDigitPosition(char input[], int start) {
  793.         for (int c = start; c < input.length && c >= 0; c++)
  794.             if (input[c] >= '0' && input[c] <= '9')
  795.                 return c;
  796.         return -1;
  797.     }
  798.  
  799.     private static int getFirstNonDigitPosition(char input[], int start) {
  800.         for (int c = start; c < input.length && c >= 0; c++)
  801.             if (input[c] < '0' || input[c] > '9')
  802.                 return c;
  803.         return input.length;
  804.     }
  805.  
  806.     private static boolean isNotAlphanumeric(char c) {
  807.         return !isLetter(c) && !isDigit(c);
  808.     }
  809.  
  810.     private static boolean isDigitOrSymbol(char c) {
  811.         return c < 'a' || c > 'z' || c == 'v' || c == 'x' || c == 'j'
  812.                 || c == 'q' || c == 'z';
  813.     }
  814.  
  815.     private static boolean isLetter(char c) {
  816.         return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
  817.     }
  818.  
  819.     private static boolean isDigit(char c) {
  820.         return c >= '0' && c <= '9';
  821.     }
  822.  
  823.     private static boolean isLowerCaseLetter(char c) {
  824.         return c >= 'a' && c <= 'z';
  825.     }
  826.  
  827.     private static boolean isUpperCaseLetter(char c) {
  828.         return c >= 'A' && c <= 'Z';
  829.     }
  830.  
  831.     private static boolean charactersMatchFragment(char input[]) {
  832.         boolean noLetters = true;
  833.         for (int c = 0; c < input.length; c++)
  834.             if (!isDigit(input[c]) && input[c] != 0)
  835.                 noLetters = false;
  836.  
  837.         if (noLetters)
  838.             return true;
  839.  
  840.         int hashCode = hashCode(input);
  841.         int fragmentId = 0;
  842.         int fragmentCount = fragments.length - 1;
  843.         if (hashCode == fragments[fragmentId]
  844.                 || hashCode == fragments[fragmentCount])
  845.             return true;
  846.         do {
  847.             int id = (fragmentId + fragmentCount) / 2;
  848.             if (hashCode == fragments[id])
  849.                 return true;
  850.             if (hashCode < fragments[id])
  851.                 fragmentCount = id;
  852.             else
  853.                 fragmentId = id;
  854.         } while (fragmentId != fragmentCount && fragmentId + 1 != fragmentCount);
  855.         return false;
  856.     }
  857.  
  858.     private static int hashCode(char input[]) {
  859.         if (input.length > 6)
  860.             return 0;
  861.         int code = 0;
  862.         for (int pos = 0; pos < input.length; pos++) {
  863.             char c = input[input.length - pos - 1];
  864.             if (c >= 'a' && c <= 'z')
  865.                 code = code * 38 + ((c - 97) + 1);
  866.             else if (c == '\'')
  867.                 code = code * 38 + 27;
  868.             else if (c >= '0' && c <= '9')
  869.                 code = code * 38 + ((c - 48) + 28);
  870.             else if (c != 0)
  871.                 return 0;
  872.         }
  873.  
  874.         return code;
  875.     }
  876.  
  877.     private static int[] fragments;
  878.     private static char[][] badWords;
  879.     private static byte[][][] badBytes;
  880.     private static char[][] domains;
  881.     private static char[][] topLevelDomains;
  882.     private static int[] topLevelDomainType;
  883.     private static final String[] exceptions = { "cook", "cook's", "cooks",
  884.             "seeks", "sheet", "woop", "woops", "faq", "noob", "noobs" };
  885. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement