Skip to content

Instantly share code, notes, and snippets.

@eddwo
Created April 19, 2013 20:44
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save eddwo/5423102 to your computer and use it in GitHub Desktop.
Save eddwo/5423102 to your computer and use it in GitHub Desktop.
Comment spam generator based on the template discovered by Scott Hanselman https://gist.github.com/shanselman/5422230
abstract class Comment
{
public abstract void Generate(StringBuilder builder);
public string Generate()
{
StringBuilder builder = new StringBuilder();
this.Generate(builder);
return builder.ToString();
}
}
class Choice : Comment
{
private readonly string[] _words;
private Random _random;
public Choice(TemplateParser parser)
{
_words = parser.ParseChoice();
_random = new Random();
}
public override void Generate(StringBuilder builder)
{
builder.Append(_words[_random.Next(_words.Length - 1)]);
}
public override string ToString()
{
string choiceWords = "{";
for (int i = 0; i < _words.Length; i++)
{
if (i > 0) choiceWords += '|';
choiceWords += _words[i];
}
choiceWords += '}';
return choiceWords;
}
}
class Sequence : Comment
{
private readonly Comment[] _sequence;
public Sequence(TemplateParser parser)
{
_sequence = parser.ParseSequence();
}
public override void Generate(StringBuilder builder)
{
foreach (Comment comm in _sequence)
{
comm.Generate(builder);
}
}
public override string ToString()
{
StringBuilder builder = new StringBuilder();
foreach (Comment comm in _sequence)
{
builder.Append(comm.ToString());
}
return builder.ToString();
}
}
class Words : Comment
{
private readonly string _words;
public Words(TemplateParser parser)
{
_words = parser.ParseWords();
}
public override void Generate(StringBuilder builder)
{
builder.Append(_words);
}
public override string ToString()
{
return _words;
}
}
class TemplateParser
{
const char _startChoice = '{';
const char _choiceOption = '|';
const char _endSequence = '|';
const char _endChoice = '}';
private readonly char[] _buffer;
private int _charPos;
public TemplateParser(string templateFile)
{
using (TextReader reader = new StreamReader(templateFile))
{
_buffer = reader.ReadToEnd().ToCharArray();
}
}
public IEnumerable<Comment> ParseTemplate()
{
_charPos = 1;
while (_charPos < _buffer.Length)
{
yield return new Sequence(this);
}
}
public Comment[] ParseSequence()
{
List<Comment> parts = new List<Comment>();
for (; _charPos < _buffer.Length; _charPos++)
{
switch (_buffer[_charPos])
{
case _startChoice:
_charPos++;
parts.Add(new Choice(this));
_charPos--;
break;
case _endSequence:
_charPos++;
return parts.ToArray();
default:
parts.Add(new Words(this));
_charPos--;
break;
}
}
return parts.ToArray();
}
public string[] ParseChoice()
{
int fromPos = _charPos;
List<string> words = new List<string>();
for (_charPos = fromPos; _charPos < _buffer.Length; _charPos++)
{
switch (_buffer[_charPos])
{
case _choiceOption:
words.Add(new String(_buffer, fromPos, _charPos - fromPos));
fromPos = _charPos + 1;
break;
case _endChoice:
words.Add(new String(_buffer, fromPos, _charPos - fromPos));
_charPos++;
return words.ToArray();
}
}
return words.ToArray();
}
public string ParseWords()
{
int fromPos = _charPos;
string words = String.Empty;
for (_charPos = fromPos; _charPos < _buffer.Length; _charPos++)
{
switch (_buffer[_charPos])
{
case _startChoice:
case _endSequence:
words = new String(_buffer, fromPos, _charPos - fromPos);
return words;
}
}
return words;
}
}
@eddwo
Copy link
Author

eddwo commented Apr 24, 2013

BTW. I hope nobody is actually intending to use this to spam comments on other peoples blogs.
I only wrote this as an exercise to experiment with various design choices.
Not saying it's anything special, just something I rushed out, not 'production' code, (whatever that is !?)

@smpeters
Copy link

For a spammer, this is high quality stuff.

@Otto42
Copy link

Otto42 commented Apr 26, 2013

Neat code, but you may have been reinventing the wheel here. :)

That format is called "spintax", and it's widely used by spammers and black hat seo types all the time. Much software already exists to parse it properly.

Google for "PHP spintax" and you'll find half a dozen libraries to parse and generate from that sort of source material.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment