So I have seen Unicode being exploited to produce a big scary looking mess of characters from a normal input text, better known as Zalgo text. HTML (edit: javascript) seems to do a wonderful job at that. So I was wondering, can same (or something similar) be done in Java? I'm relatively new to it, so I think making a similar generator would be a good exercise.
EDIT to show how to do it in java.
The result is saved in the text file zalgo.txt in unicode format. We save it to a file because your IDE might not know how to display the unicode characters properly if you write it to the outputstream.
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
public class Zalgo {
private static final char[] zalgo_up =
{ '\u030d', /* Ì? */'\u030e', /* ÌŽ */'\u0304', /* Ì„ */'\u0305', /* Ì… */
'\u033f', /* Ì¿ */'\u0311', /* Ì‘ */'\u0306', /* ̆ */'\u0310', /* Ì? */
'\u0352', /* ͒ */'\u0357', /* ͗ */'\u0351', /* ͑ */'\u0307', /* ̇ */
'\u0308', /* ̈ */'\u030a', /* ̊ */'\u0342', /* ͂ */'\u0343', /* ̓ */
'\u0344', /* ̈Ì? */'\u034a', /* ÍŠ */'\u034b', /* Í‹ */'\u034c', /* ÍŒ */
'\u0303', /* ̃ */'\u0302', /* Ì‚ */'\u030c', /* ÌŒ */'\u0350', /* Í? */
'\u0300', /* Ì€ */'\u0301', /* Ì? */'\u030b', /* Ì‹ */'\u030f', /* Ì? */
'\u0312', /* ̒ */'\u0313', /* ̓ */'\u0314', /* ̔ */'\u033d', /* ̽ */
'\u0309', /* ̉ */'\u0363', /* ͣ */'\u0364', /* ͤ */'\u0365', /* ͥ */
'\u0366', /* ͦ */'\u0367', /* ͧ */'\u0368', /* ͨ */'\u0369', /* ͩ */
'\u036a', /* ͪ */'\u036b', /* Í« */'\u036c', /* ͬ */'\u036d', /* Í */
'\u036e', /* ͮ */'\u036f', /* ͯ */'\u033e', /* ̾ */'\u035b', /* ͛ */
'\u0346', /* ͆ */'\u031a' /* ̚ */
} ;
private static final char[] zalgo_down =
{ '\u0316', /* ̖ */'\u0317', /* ̗ */'\u0318', /* ̘ */'\u0319', /* ̙ */
'\u031c', /* Ìœ */'\u031d', /* Ì? */'\u031e', /* Ìž */'\u031f', /* ÌŸ */
'\u0320', /* Ì */'\u0324', /* ̤ */'\u0325', /* Ì¥ */'\u0326', /* ̦ */
'\u0329', /* ̩ */'\u032a', /* ̪ */'\u032b', /* ̫ */'\u032c', /* ̬ */
'\u032d', /* Ì */'\u032e', /* Ì® */'\u032f', /* ̯ */'\u0330', /* Ì° */
'\u0331', /* ̱ */'\u0332', /* ̲ */'\u0333', /* ̳ */'\u0339', /* ̹ */
'\u033a', /* ̺ */'\u033b', /* ̻ */'\u033c', /* ̼ */'\u0345', /* ͅ */
'\u0347', /* ͇ */'\u0348', /* ͈ */'\u0349', /* ͉ */'\u034d', /* Í? */
'\u034e', /* ÍŽ */'\u0353', /* Í“ */'\u0354', /* Í” */'\u0355', /* Í• */
'\u0356', /* ͖ */'\u0359', /* ͙ */'\u035a', /* ͚ */'\u0323' /* ̣ */
} ;
//those always stay in the middle
private static final char[] zalgo_mid =
{ '\u0315', /* Ì• */'\u031b', /* Ì› */'\u0340', /* Ì€ */'\u0341', /* Ì? */
'\u0358', /* ͘ */'\u0321', /* ̡ */'\u0322', /* ̢ */'\u0327', /* ̧ */
'\u0328', /* ̨ */'\u0334', /* ̴ */'\u0335', /* ̵ */'\u0336', /* ̶ */
'\u034f', /* Í? */'\u035c', /* Íœ */'\u035d', /* Í? */'\u035e', /* Íž */
'\u035f', /* ÍŸ */'\u0360', /* Í */'\u0362', /* Í¢ */'\u0338', /* ̸ */
'\u0337', /* Ì· */'\u0361', /* Í¡ */'\u0489' /* Ò‰_ */
} ;
// rand funcs
//---------------------------------------------------
//gets an int between 0 and max
private static int rand(int max) {
return (int)Math.floor(Math.random() * max);
}
//gets a random char from a zalgo char table
private static char rand_zalgo(char[] array) {
int ind = (int)Math.floor(Math.random() * array.length);
return array[ind];
}
//hide show element
//lookup char to know if its a zalgo char or not
private static boolean is_zalgo_char(char c) {
for (int i = 0; i < zalgo_up.length; i++)
if (c == zalgo_up[i])
return true;
for (int i = 0; i < zalgo_down.length; i++)
if (c == zalgo_down[i])
return true;
for (int i = 0; i < zalgo_mid.length; i++)
if (c == zalgo_mid[i])
return true;
return false;
}
public static String goZalgo(String iText, boolean zalgo_opt_mini, boolean zalgo_opt_normal, boolean up,
boolean down, boolean mid) {
String zalgoTxt = "";
for (int i = 0; i < iText.length(); i++) {
if (is_zalgo_char(iText.charAt(i)))
continue;
int num_up;
int num_mid;
int num_down;
//add the normal character
zalgoTxt += iText.charAt(i);
//options
if (zalgo_opt_mini) {
num_up = rand(8);
num_mid = rand(2);
num_down = rand(8);
} else if (zalgo_opt_normal) {
num_up = rand(16) / 2 + 1;
num_mid = rand(6) / 2;
num_down = rand(16) / 2 + 1;
} else //maxi
{
num_up = rand(64) / 4 + 3;
num_mid = rand(16) / 4 + 1;
num_down = rand(64) / 4 + 3;
}
if (up)
for (int j = 0; j < num_up; j++)
zalgoTxt += rand_zalgo(zalgo_up);
if (mid)
for (int j = 0; j < num_mid; j++)
zalgoTxt += rand_zalgo(zalgo_mid);
if (down)
for (int j = 0; j < num_down; j++)
zalgoTxt += rand_zalgo(zalgo_down);
}
return zalgoTxt;
}
public static void main(String[] args){
final String zalgoTxt = goZalgo("To invoke the hive-mind representing chaos.\n" +
"Invoking the feeling of chaos.\n" +
"With out order.\n" +
"The Nezperdian hive-mind of chaos. Zalgo. \n" +
"He who Waits Behind The Wall.\n" +
"ZALGO!", true, false, true, true, true);
try {
final File fileDir = new File("zalgo.txt");
final Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileDir), "UTF8"));
final String[] lines = zalgoTxt.split("\n");
for (int i = 0; i < lines.length; i++) {
String line = lines[i];
out.append(line).append("\r\n");;
}
out.flush();
out.close();
} catch (UnsupportedEncodingException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
If you look carefully here (another zalgo generator):
http://textozor.com/zalgo-text/
You can see that it uses javascript to generate the messed up code: http://textozor.com/zalgo-text/scriptz.js
Convert that logic into any language you want.