EDIT (Disclaimer): There is some profanity in this post, but I assure you it is only being used for a better cause.
After reading threads about filtering out incoming data from battle.net as a means of protection, I started work on a plug-able filtering system for character arrays. It is nothing special at the moment, but it does contain some of what I consider bare essentials for a filtering system. Future versions will use class loaders, to allow individual programmers a way to make their own filters.
Filter.java:
This is the interface for filters. It makes it so I can create new filters, without modifying existing code through inheritance.
/**
* Interface for filters.
* @author Tuberload
* @version 1.0
*/
public interface Filter
{
/**
* Executes the filter.
* @param data The data to be filtered.
*/
public CharBuffer execute (CharBuffer data);
/**
* Returns the version of the filter.
*/
public String version();
/**
* Returns the author of the filter.
*/
public String author();
}
ProfanityFilter.java:
A simple example of how a filter might work.
/**
* Filters out common profanity.
* @author Tuberload
* @version 1.0
*/
public class ProfanityFilter implements Filter
{
private static final String[] PROFANITY =
{ "shit", "fuck", "ass", "bitch", "pussy", "dick", "whore", "slut" };
private static final char REPLACEMENT = '#';
/**
* Executes the filter.
* @param data The data to be filtered.
* @return Filtered data.
*/
public CharBuffer execute (CharBuffer data)
{
if (data != null)
{
int index = 0;
for (int i = 0; i < PROFANITY.length; i++)
{
index = data.indexOf (PROFANITY[i].toCharArray());
if (index != -1)
{
data.fillRegion (index, PROFANITY[i].length()-1,
REPLACEMENT);
}
}
}
return data;
}
/**
* Returns the author of the filter.
*/
public String author()
{
return new String ("Tuberload");
}
/**
* Returns the version of the filter
*/
public String version()
{
return new String ("v1.0");
}
}
CharBuffer.java:
A wrapper for char[] arrays to add whatever functionality I think is necessary. I know there is probably some pre-made classes for this in the Java API, but what's the fun in that.
/**
* Character buffer
* @author Tuberload
* @version 1.0
*/
public class CharBuffer
{
private char[] buffer;
private static final int DEF_BUF_LEN = 256;
/**
* Create a new DataBuffer and populate it with data.
* @param data The data to be inserted into the buffer.
*/
public CharBuffer (char[] data)
{
int dataLength = data.length;
if (dataLength > 0)
{
buffer = new char[dataLength];
System.arraycopy (data, 0, buffer, 0, dataLength);
}
else
{
buffer = new char[DEF_BUF_LEN];
}
}
/**
* Gets characters from the buffer.
* @param srcBegin The index of the first character to be retrieved.
* @param srcEnd The index of the last character the be retrieved.
*/
public char[] getChars (int srcBegin, int srcEnd)
{
int length = srcEnd - srcBegin;
char[] data = new char[length];
System.arraycopy (buffer, srcBegin, data, 0, length);
return data;
}
/**
* Retrieves the entire data buffer.
*/
public char[] getChars()
{
return buffer;
}
/**
* Replace a region of the data buffer.
* @param start The index of the region to be replaced.
* @param data Data to be inserted into the buffer.
*/
public void replaceRegion (int start, char[] data)
{
int pos = 0;
for (int i = start; i < data.length; i++)
{
buffer[i] = data[pos++];
}
}
/**
* Fill a region of the data buffer with a specific character.
* @param start The index of the region to be replaced.
* @param length Length of region to be filled.
* @param replacement The character used to fill the region
*/
public void fillRegion (int start, int length, char replacement)
{
for (int i = start; i <= start+length; i++)
{
buffer[i] = replacement;
}
}
/**
* Finds the index of a character array inside of the buffer.
* @param data Data to look for inside of the buffer.
* @return The index of the data. -1 if array not found.
*/
public int indexOf (char[] data)
{
int contains = -1; // If data array is not found -1 will be returned
if (data != null && data.length > 0)
{
int pos = 0; // Position inside of data array
for (int i = 0; i < buffer.length; i++)
{
if (buffer[i] == data[pos++]) // A match was found
{
if (pos == data.length) // Check if data array found
{
contains = i-data.length+1; // Index of data array
// in the buffer
break;
}
}
else // A match was not found
{
if (pos != 0) // Check if the position in data was > 0 and if
// so restart the search at failed index
{
pos = 0;
if (buffer[i] == data[pos++]);
else pos = 0;
}
}
}
}
return contains;
}
}
FilterTest.java:
A quick example of how to use the filtering system.
public class FilterTest
{
public static void main (String[] args)
{
String data = "This is so fucking cool asshole";
CharBuffer buffer = new CharBuffer (data.toCharArray());
System.out.println (buffer.getChars());
ProfanityFilter filter = new ProfanityFilter ();
buffer = filter.execute (buffer);
System.out.println (buffer.getChars());
}
}
A minor comment about your choice of filters -- as written, it'd be bad for you to filter "ass", because you're not detecting its use in larger words, such as assignment. :P
Don't forget how bad Dick will feel either.
Quote from: Kp on February 21, 2004, 11:46 AM
A minor comment about your choice of filters -- as written, it'd be bad for you to filter "ass", because you're not detecting its use in larger words, such as assignment. :P
True; it would be better to perhaps use regular expressions and do something like (^|\W)ass(\W|$)
Quote from: K on February 22, 2004, 03:13 PM
Quote from: Kp on February 21, 2004, 11:46 AM
A minor comment about your choice of filters -- as written, it'd be bad for you to filter "ass", because you're not detecting its use in larger words, such as assignment. :P
True; it would be better to perhaps use regular expressions and do something like (^|\W)ass(\W|$)
Bah! ;) I will modify the code using my own algorithms here soon. Plus I have a few other fixes/additions to add as well.
Look up perltools. It lets you use perl regular expressions, like mystr = perltools.filter(mystr, "s/ass/bum/g");
import java.nio.regex