JSFiddle - React, Tailwind, and code Playground
by Abdul Ahmad
JavaScript
const _badWords = ['fool', "silly", "fork"];
/*
root -> f -> o -> o -> l
-> 0 -> o -> l
-> 0 -> l
-> r -> k
s -> i
s {
}
$ {
}
5 {
}
*/
const _substitutions = {
'o': ['0'],
'l': ['1', '|'],
'i': ['1', '!'],
's': ['$', '5'],
'r': ['4'],
};
const trie = {
char: '',
children: {
},
};
function generateTrie(badWords, subs) {
badWords.forEach(w => {
processWord(w, subs, trie);
});
}
function processWord(w, subs, node) {
let lastNode = node;
for (let i = 0; i < w.length; i++) {
const c = w.charAt(i);
if (lastNode.children[c]) {
lastNode = lastNode.children[c];
continue;
}
const node = {
char: c,
children: {},
};
lastNode.children[c] = node;
if (subs[c]) {
subs[c].forEach(s => {
const remainingLetters = w.slice(i + 1);
const subNode = { c: s, children: {}};
processWord(remainingLetters, subs, subNode);
});
}
lastNode = node;
}
}
generateTrie(_badWords, _substitutions);
console.log(trie);
function badWordPresent(word) {
}
/* We run a service that allows people to pick their username, sometimes people put bad words in their username and we would like to prevent this.
Our customer support team has identified the most serious bad words
String[] bad_words = {"fool", "silly", "fork"};
We write the simplest MVP possible, simply loop over the bad words and do a contains check. This works wonderfully until an elite hacker shows up and makes their username
mrf00l
By replacing the o character with 0 they have defeated the detector and their name appears fine to our code but nefarious to our users. Customer Support is able to find the most common replacements
Map<Character, Character[]> substitutions = new HashMap<Character, Character[]> {
{
put('o', new Character[] {'0'},
put('l', new Character[] {'1', '|'},
...