Skip to content

Instantly share code, notes, and snippets.

@RobThree
Created August 29, 2013 10:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RobThree/6376330 to your computer and use it in GitHub Desktop.
Save RobThree/6376330 to your computer and use it in GitHub Desktop.
using System;
using System.Linq;
using System.Text;
//Demonstrate usage
class Program
{
static void Main(string[] args)
{
var ww = new WhitespaceWatermarker();
var watermarkedtext = ww.Watermark("Lorem ipsum\r\ndolor sit amet", "s3cr3t");
var watermark = ww.ReadWatermark(watermarkedtext);
}
}
/// <summary>
/// Contains functions for 'watermarking' plain text using whitespace (tabs and spaces).
/// </summary>
/// <remarks>
/// This class is written purely as an academic exercise and as "proof of concept".
/// </remarks>
public class WhitespaceWatermarker
{
/// <summary>
/// "Watermarks" a text by appending whitespace at the end of the string.
/// </summary>
/// <param name="text">The string to watermark.</param>
/// <param name="watermark">The watermark to add to the text.</param>
/// <returns>Returns the watermarked text.</returns>
/// <exception cref="ArgumentNullException">Thrown when either text or watermark is null.</exception>
public string Watermark(string text, string watermark)
{
if (text == null)
throw new ArgumentNullException("text");
if (watermark == null)
throw new ArgumentNullException("watermark");
var w = new StringBuilder().AppendLine(text); //Initialize stringbuilder and ensure a newline is appended at the end
for (int i = 0; i < watermark.Length; i++) //Iterate each char in watermark and "encode" to "binary" (0 = \t, 1 = <space>)
w.Append(Convert.ToString(watermark[i], 2).PadLeft(8, '0').Replace('0', '\t').Replace('1', ' '));
return w.ToString();
}
/// <summary>
/// Reads a watermark (if any) from a text.
/// </summary>
/// <param name="text">The string to extract the watermark from (if any).</param>
/// <returns>Returns the watermark (if any) found in the text.</returns>
/// <exception cref="ArgumentNullException">Thrown when text is null.</exception>
/// <exception cref="FormatException">Thrown when text doesn't contain a watermark.</exception>
public string ReadWatermark(string text)
{
if (text == null)
throw new ArgumentNullException("text");
var w = text.Split(new[] { '\r', '\n' }).Last(); //Get last line (should be watermark)
//Watermark length should be > 0 and a multiple of 8 and should be whitespace
if (!string.IsNullOrWhiteSpace(w) || (w.Length == 0) || (w.Length % 8 != 0))
throw new FormatException("No watermark detected");
var d = new StringBuilder();
var x = w.Replace('\t', '0').Replace(' ', '1'); //"Decode" tabs/spaces back to zeroes and ones
for (int i = 0; i < x.Length; i += 8) //Iterate "binary string" and "decode" each char
d.Append((char)Convert.ToByte(x.Substring(i, 8), 2));
return d.ToString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment