├── .gitignore ├── Makefile ├── README.md └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | zalgo 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: zalgo 2 | 3 | zalgo: main.cpp 4 | $(CXX) main.cpp -std=c++17 -lstdc++ -o zalgo -Wall -Wextra -Wpedantic 5 | 6 | install: zalgo Makefile 7 | cp zalgo /usr/local/bin/zalgo 8 | 9 | clean: 10 | rm -f zalgo 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # zalgo 2 | 3 | **zalgo** is a small utility that reads stdin and corrupts it with combining diacritics. 4 | 5 | ### Options: 6 | 7 | ``` 8 | -h,--help Display this help message 9 | -u,--up Fuck up going up 10 | -m,--middle Fuck up the middle 11 | -d,--down Fuck up going down 12 | -s,--strength Choose how strong to fuck up, from 0-3: 13 | 0: micro fuck up 14 | 1: mini fuck up 15 | 2: normal fuck up 16 | 3: maxi fuck up 17 | ``` 18 | 19 | By default, it will act as if you'd specified `-md -s1`. 20 | 21 | 22 | ### Example usage: 23 | 24 | ``` 25 | luna:~/code/zalgo$ make | zalgo 26 | m̢̥a̙͈̖̝̩̘k̡̖̩̹̤͈͙̖e̬̮̼͎̥͟ͅ: Ņ̲̟͎͓̭o̧͔͙̗͓t̥̜͖̥h͈̺į͇n͕̪̻̫̹g̫͈̲͙͕͜ t̯͇̙o b͚e̶͇ d͙o͍n̳̣̠͝e͔̠͕̠͓ f̳̝o̲̬͎͍̲͉͍r͏ `a̵̩̯̬̣̫̹̤l̛̼̪̥͚̫̱l̼͔̙̯̜͉'. 27 | ``` 28 | 29 | Adapted from the zalgo text generator at eeemo.net 30 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | bool g_hasSetDirection = false; 8 | bool g_fuckUpGoingUp = false; 9 | bool g_fuckUpTheMiddle = false; 10 | bool g_fuckUpGoingDown = false; 11 | 12 | int g_strength = 1; 13 | 14 | const std::vector zalgo_up = { 15 | 0x030d, 0x030e, 0x0304, 0x0305, 16 | 0x033f, 0x0311, 0x0306, 0x0310, 17 | 0x0352, 0x0357, 0x0351, 0x0307, 18 | 0x0308, 0x030a, 0x0342, 0x0343, 19 | 0x0344, 0x034a, 0x034b, 0x034c, 20 | 0x0303, 0x0302, 0x030c, 0x0350, 21 | 0x0300, 0x0301, 0x030b, 0x030f, 22 | 0x0312, 0x0313, 0x0314, 0x033d, 23 | 0x0309, 0x0363, 0x0364, 0x0365, 24 | 0x0366, 0x0367, 0x0368, 0x0369, 25 | 0x036a, 0x036b, 0x036c, 0x036d, 26 | 0x036e, 0x036f, 0x033e, 0x035b, 27 | 0x0346, 0x031a 28 | }; 29 | 30 | const std::vector zalgo_down = { 31 | 0x0316, 0x0317, 0x0318, 0x0319, 32 | 0x031c, 0x031d, 0x031e, 0x031f, 33 | 0x0320, 0x0324, 0x0325, 0x0326, 34 | 0x0329, 0x032a, 0x032b, 0x032c, 35 | 0x032d, 0x032e, 0x032f, 0x0330, 36 | 0x0331, 0x0332, 0x0333, 0x0339, 37 | 0x033a, 0x033b, 0x033c, 0x0345, 38 | 0x0347, 0x0348, 0x0349, 0x034d, 39 | 0x034e, 0x0353, 0x0354, 0x0355, 40 | 0x0356, 0x0359, 0x035a, 0x0323 41 | }; 42 | 43 | const std::vector zalgo_mid = { 44 | 0x0315, 0x031b, 0x0340, 0x0341, 45 | 0x0358, 0x0321, 0x0322, 0x0327, 46 | 0x0328, 0x0334, 0x0335, 0x0336, 47 | 0x034f, 0x035c, 0x035d, 0x035e, 48 | 0x035f, 0x0360, 0x0362, 0x0338, 49 | 0x0337, 0x0361, 50 | //0x0489, // adds sideways padding in macOS terminal for some reason 51 | }; 52 | 53 | void printRandZalgo(const std::vector& arr) 54 | { 55 | const uint32_t value = arr[rand() % arr.size()]; 56 | 57 | const char buffer[3] = { 58 | (char)(0xc0 | ((value >> 6) & 0x1f)), 59 | (char)(0x80 | (value & 0x3f)), 60 | (char)0x00 61 | }; 62 | 63 | fputs(buffer, stdout); 64 | } 65 | 66 | void printHelp() 67 | { 68 | printf("zalgo\n\n"); 69 | printf("Options:\n"); 70 | printf(" -h,--help Display this help message\n"); 71 | printf(" -u,--up Fuck up going up\n"); 72 | printf(" -m,--middle Fuck up the middle\n"); 73 | printf(" -d,--down Fuck up going down\n"); 74 | printf(" -s,--strength Choose how strong to fuck up, from 0-3:\n"); 75 | printf(" 0: micro fuck up\n"); 76 | printf(" 1: mini fuck up\n"); 77 | printf(" 2: normal fuck up\n"); 78 | printf(" 3: maxi fuck up\n"); 79 | } 80 | 81 | void parseCommandLine(int argc, char** argv) 82 | { 83 | while (1) { 84 | static struct option long_options[] = { 85 | { "up", no_argument, 0, 'u' }, 86 | { "middle", no_argument, 0, 'm' }, 87 | { "down", no_argument, 0, 'd' }, 88 | { "strength", required_argument, 0, 's' }, 89 | { "help", no_argument, 0, 'h' }, 90 | { 0, 0, 0, 0 } 91 | }; 92 | 93 | int option_index = 0; 94 | const int c = getopt_long(argc, argv, "umds:h", long_options, &option_index); 95 | 96 | if (c == -1) 97 | break; 98 | 99 | switch (c) { 100 | case 'u': { g_fuckUpGoingUp = true; g_hasSetDirection = true; break; } 101 | case 'm': { g_fuckUpTheMiddle = true; g_hasSetDirection = true; break; } 102 | case 'd': { g_fuckUpGoingDown = true; g_hasSetDirection = true; break; } 103 | case 's': { 104 | g_strength = std::max(std::min(atoi(optarg), 3), 0); 105 | break; 106 | } 107 | case 'h': { 108 | printHelp(); 109 | exit(0); 110 | } 111 | } 112 | } 113 | 114 | // default options 115 | if (!g_hasSetDirection) 116 | { 117 | g_fuckUpGoingUp = false; 118 | g_fuckUpTheMiddle = true; 119 | g_fuckUpGoingDown = true; 120 | } 121 | } 122 | 123 | int main(int argc, char** argv) 124 | { 125 | parseCommandLine(argc, argv); 126 | 127 | int c; 128 | bool isInEscapeCode = false; 129 | while ((c = getchar()) > 0) 130 | { 131 | putc((char)c, stdout); 132 | 133 | if (c == 0x1B && !isInEscapeCode) 134 | { 135 | isInEscapeCode = true; 136 | continue; 137 | } 138 | else if (isInEscapeCode && c >= 0x40 && c <= 0x7e) 139 | { 140 | isInEscapeCode = false; 141 | continue; 142 | } 143 | 144 | if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) 145 | { 146 | int num_up = 0; 147 | int num_mid = 0; 148 | int num_down = 0; 149 | 150 | if (g_strength == 0) 151 | { 152 | num_up = (rand() % 3) == 0 ? 1 : 0; 153 | num_mid = (rand() % 3) == 0 ? 1 : 0; 154 | num_down = (rand() % 3) == 0 ? 1 : 0; 155 | } 156 | else if (g_strength == 1) 157 | { 158 | num_up = (rand() % 4); 159 | num_mid = (rand() % 2); 160 | num_down = (rand() % 4); 161 | } 162 | else if (g_strength == 2) 163 | { 164 | num_up = (rand() % 6) + 1; 165 | num_mid = (rand() % 3); 166 | num_down = (rand() % 6) + 1; 167 | } 168 | else if (g_strength == 3) 169 | { 170 | num_up = (rand() % 16) + 3; 171 | num_mid = (rand() % 4) + 1; 172 | num_down = (rand() % 16) + 3; 173 | } 174 | 175 | if (g_fuckUpGoingUp) 176 | for (int j = 0; j < num_up; j++) 177 | printRandZalgo(zalgo_up); 178 | 179 | if (g_fuckUpTheMiddle) 180 | for (int j = 0; j < num_mid; j++) 181 | printRandZalgo(zalgo_mid); 182 | 183 | if (g_fuckUpGoingDown) 184 | for (int j = 0; j < num_down; j++) 185 | printRandZalgo(zalgo_down); 186 | } 187 | } 188 | return 0; 189 | } 190 | --------------------------------------------------------------------------------