javahtmlunicodezalgo

Zalgo text in Java?


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.


Solution

  • 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.