Как можно предотвратить текст Zalgo?
Я читал о том, как работает текст Zalgo, и я хочу узнать, как программное обеспечение чата или форума может предотвратить такое раздражение? Точнее говоря, что такое полный набор символов Unicode, который должен:
а) либо быть раздетым, предполагая, что участники чата должны использовать только языки, которые не требуют комбинированных меток (то есть вы могли бы написать "жених" с комбинированной меткой, но вы были бы немного Зальго сами, если бы вы настаивали на выполнении так); или же,
б) уменьшено до максимум 8 последовательных символов ( максимум встречается в реальных языках).
РЕДАКТИРОВАТЬ: Тем временем я нашел совершенно другой вопрос (" Как защититься от... диакритики?"), Который по сути такой же, как этот. Я сделал его название более явным, чтобы другие тоже его нашли.
5 ответов
Если вы очень серьезно относитесь к этому и хотите получить техническое решение, вы можете сделать следующее:
- Разбить входящий текст на более мелкие единицы (слова или предложения);
- Визуализируйте каждую единицу на сервере с выбранным шрифтом (с огромной высотой строки и большим количеством места под базовой линией, где будет проходить "шум"Zalgo);
- Обучите алгоритм машинного обучения, чтобы судить, выглядит ли он слишком "темным" и "занятым";
- Если алгоритм имеет низкую достоверность, откладывайте на модераторов-людей.
Это может быть весело реализовать, но на практике, вероятно, лучше сразу перейти к четвертому шагу.
Редактировать: Вот более практичное, хотя и грубое, решение в Python 2.7. Символы Юникода, классифицированные как "Пометить без пробелов" и "Пометить внутри", являются основными инструментами, используемыми для создания эффекта Зальго. В отличие от приведенной выше идеи, он не будет пытаться определить "эстетику" текста, а просто удалит все такие символы. (Само собой разумеется, это будет мусор текста на многих языках. Читайте дальше для лучшего решения.) Чтобы отфильтровать больше категорий символов, добавьте их в ZALGO_CHAR_CATEGORIES
,
#!/usr/bin/env python
import unicodedata
import codecs
ZALGO_CHAR_CATEGORIES = ['Mn', 'Me']
with codecs.open("zalgo", 'r', 'utf-8') as infile:
for line in infile:
print ''.join([c for c in unicodedata.normalize('NFD', line) if unicodedata.category(c) not in ZALGO_CHAR_CATEGORIES]),
Пример ввода:
1
H̡̫̤ͭ̓̓̇͗̎̀ơ̯̗͒̄̀̈ͤ̀͡w͓̲͙͋ͬ̊ͦ̂̀̚ ͎͉͖̌ͯͅͅd̳̘̿̃̔̏ͣ͂̉̕ŏ̖̙͋ͤ̊͗̓͟͜e͈͕̯̮͌ͭ̍̐̃͒s͙͔̺͇̗̱̿̊̇͞ ̸ͩͩ͑̋̀ͮͥͦ̊Z̆̊͊҉҉̠̱̦̩͕ą̟̹͈̺̹̋̅ͯĺ̡̘̹̻̩̩͋͘g̪͚͗ͬ͒o̢̖͇̬͍͇̔͋͊̓ ̢͈͂ͣ̏̿͐͂ͯ͠t̛͓̖̻̲ͤ̈ͣ͝e͋̄ͬ̽͜҉͚̭͇ͅx̌ͤ̓̂̓͐͐́͋͡ț̗̹̄̌̀ͧͩ̕͢ ̮̗̩̳̱̾w͎̭̤̄͗ͭ̃͗ͮ̐o̢̯̻̾ͣͬ̽̔̍͟r̢̪͙͍̠̀ͅǩ̵̶̗̮̮ͪ́?̙͉̥̬ͤ̌͗ͩ̕͡
2
H̡̫̤ͭ̓̓̇͗̎̀ơ̯̗͒̄̀̈ͤ̀͡w͓̲͙͋ͬ̊ͦ̂̀̚ ͎͉͖̌ͯͅͅd̳̘̿̃̔̏ͣ͂̉̕ŏ̖̙͋ͤ̊͗̓͟͜e͈͕̯̮͌ͭ̍̐̃͒s͙͔̺͇̗̱̿̊̇͞ ̸ͩͩ͑̋̀ͮͥͦ̊Z̆̊͊҉҉̠̱̦̩͕ą̟̹͈̺̹̋̅ͯĺ̡̘̹̻̩̩͋͘g̪͚͗ͬ͒o̢̖͇̬͍͇̔͋͊̓ ̢͈͂ͣ̏̿͐͂ͯ͠t̛͓̖̻̲ͤ̈ͣ͝e͋̄ͬ̽͜҉͚̭͇ͅx̌ͤ̓̂̓͐͐́͋͡ț̗̹̄̌̀ͧͩ̕͢ ̮̗̩̳̱̾w͎̭̤̄͗ͭ̃͗ͮ̐o̢̯̻̾ͣͬ̽̔̍͟r̢̪͙͍̠̀ͅǩ̵̶̗̮̮ͪ́?̙͉̥̬ͤ̌͗ͩ̕͡
3
Выход:
1
How does Zalgo text work?
2
How does Zalgo text work?
3
Наконец, если вы хотите обнаружить, а не безоговорочно удалить текст Zalgo, вы можете выполнить анализ частоты символов. Программа ниже делает это для каждой строки входного файла. Функция is_zalgo
вычисляет "счет Zalgo" для каждого слова заданной строки (оценка - это число потенциальных символов Zalgo, деленное на общее количество символов). Затем он выглядит, если третий квартиль оценки слов больше, чем THRESHOLD
, Если THRESHOLD
равняется 0.5
это означает, что мы пытаемся определить, содержит ли каждое из четырех слов более 50% символов Zalgo. (The THRESHOLD
0,5 было угадано и может потребовать корректировки для реального использования.) Этот тип алгоритма, вероятно, является лучшим с точки зрения отдачи / усилий по кодированию.
#!/usr/bin/env python
from __future__ import division
import unicodedata
import codecs
import numpy
ZALGO_CHAR_CATEGORIES = ['Mn', 'Me']
THRESHOLD = 0.5
DEBUG = True
def is_zalgo(s):
if len(s) == 0:
return False
word_scores = []
for word in s.split():
cats = [unicodedata.category(c) for c in word]
score = sum([cats.count(banned) for banned in ZALGO_CHAR_CATEGORIES]) / len(word)
word_scores.append(score)
total_score = numpy.percentile(word_scores, 75)
if DEBUG:
print total_score
return total_score > THRESHOLD
with codecs.open("zalgo", 'r', 'utf-8') as infile:
for line in infile:
print is_zalgo(unicodedata.normalize('NFD', line)), "\t", line
Образец вывода:
0.911483990148
True Señor, could you or your fiancé explain, H̡̫̤ͭ̓̓̇͗̎̀ơ̯̗͒̄̀̈ͤ̀͡w͓̲͙͋ͬ̊ͦ̂̀̚ ͎͉͖̌ͯͅͅd̳̘̿̃̔̏ͣ͂̉̕ŏ̖̙͋ͤ̊͗̓͟͜e͈͕̯̮͌ͭ̍̐̃͒s͙͔̺͇̗̱̿̊̇͞ ̸ͩͩ͑̋̀ͮͥͦ̊Z̆̊͊҉҉̠̱̦̩͕ą̟̹͈̺̹̋̅ͯĺ̡̘̹̻̩̩͋͘g̪͚͗ͬ͒o̢̖͇̬͍͇̔͋͊̓ ̢͈͂ͣ̏̿͐͂ͯ͠t̛͓̖̻̲ͤ̈ͣ͝e͋̄ͬ̽͜҉͚̭͇ͅx̌ͤ̓̂̓͐͐́͋͡ț̗̹̄̌̀ͧͩ̕͢ ̮̗̩̳̱̾w͎̭̤̄͗ͭ̃͗ͮ̐o̢̯̻̾ͣͬ̽̔̍͟r̢̪͙͍̠̀ͅǩ̵̶̗̮̮ͪ́?̙͉̥̬ͤ̌͗ͩ̕͡
0.333333333333
False Příliš žluťoučký kůň úpěl ďábelské ódy.
Сделать коробку overflow:hidden
, На самом деле он не отключает текст Zalgo, но предотвращает повреждение других комментариев.
<style>
.comment {
/* the overflow: hidden is what prevents one comment's combining marks from affecting its siblings */
overflow: hidden;
/* the padding gives space for any legitimate combining marks */
padding: 0.5em;
/* the rest are just to visually divide the three comments */
border: solid 1px #ccc;
margin-top: -1px;
margin-bottom: -1px;
}
</style>
<div class=comment>The below comment looks aweful.</div>
<div class=comment>H̡̫̤ͭ̓̓̇͗̎̀ơ̯̗͒̄̀̈ͤ̀͡w͓̲͙͋ͬ̊ͦ̂̀̚ ͎͉͖̌ͯͅͅd̳̘̿̃̔̏ͣ͂̉̕ŏ̖̙͋ͤ̊͗̓͟͜e͈͕̯̮͌ͭ̍̐̃͒s͙͔̺͇̗̱̿̊̇͞ ̸ͩͩ͑̋̀ͮͥͦ̊Z̆̊͊҉҉̠̱̦̩͕ą̟̹͈̺̹̋̅ͯĺ̡̘̹̻̩̩͋͘g̪͚͗ͬ͒o̢̖͇̬͍͇̔͋͊̓ ̢͈͂ͣ̏̿͐͂ͯ͠t̛͓̖̻̲ͤ̈ͣ͝e͋̄ͬ̽͜҉͚̭͇ͅx̌ͤ̓̂̓͐͐́͋͡ț̗̹̄̌̀ͧͩ̕͢ ̮̗̩̳̱̾w͎̭̤̄͗ͭ̃͗ͮ̐o̢̯̻̾ͣͬ̽̔̍͟r̢̪͙͍̠̀ͅǩ̵̶̗̮̮ͪ́?̙͉̥̬ͤ̌͗ͩ̕͡</div>
<div class=comment>The above comment looks aweful.</div>
Соответствующий вопрос задавался ранее: https://stackru.com/questions/5073191/how-is-zalgo-text-implemented но здесь интересно заняться профилактикой.
С точки зрения предотвращения этого вы можете выбрать несколько стратегий:
- предотвратить полное объединение диакритических знаков (и разозлить многих международных пользователей),
- отфильтровывать комбинированные символы, используя белый или черный список (и разозлить меньший процент международных пользователей)
- предотвратить определенное количество комбинируемых символов (и разозлить еще меньший процент пользователей)
- иметь здоровое модераторское сообщество (со всеми недостатками, которые есть, смотрите ваш вопрос в качестве примера здесь)
Вы можете избавиться от текста Zalgo в своем приложении, используя метки комбинирования полос Матиаса Биненса.
Маркировка совмещения модулей доступна для браузеров (через Bower) и приложений Node.js (через npm).
Вот пример того, как использовать его с npm:
var stripCombiningMarks = require("strip-combining-marks");
var zalgoText = 'U̼̥̻̮͍͖n͠i͏c̯̮o̬̝̠͉̤d͖͟e̫̟̗͟ͅ';
var stripptedText = stripCombiningMarks(zalgoText); // "Unicode"
Используя PHP и образ мышления работника по сносу, вы можете избавиться от Zalgo с помощью функции iconv. Конечно, это убьет и любые другие символы UTF-8.
$unZalgoText = iconv("UTF-8", "ISO-8859-1//IGNORE", $zalgoText);