Skip to content

Commit 51b9fe6

Browse files
authoredFeb 15, 2025··
Merge pull request #1971 from bartblaze/master
Add Leet Speak
2 parents fed10f3 + 3cdbdf4 commit 51b9fe6

File tree

4 files changed

+149
-1
lines changed

4 files changed

+149
-1
lines changed
 

‎src/core/config/Categories.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,8 @@
274274
"Unicode Text Format",
275275
"Remove Diacritics",
276276
"Unescape Unicode Characters",
277-
"Convert to NATO alphabet"
277+
"Convert to NATO alphabet",
278+
"Convert Leet Speak"
278279
]
279280
},
280281
{
+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/**
2+
* @author bartblaze []
3+
* @copyright Crown Copyright 2025
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
9+
/**
10+
* Convert Leet Speak operation
11+
*/
12+
class ConvertLeetSpeak extends Operation {
13+
/**
14+
* ConvertLeetSpeak constructor
15+
*/
16+
constructor() {
17+
super();
18+
19+
this.name = "Convert Leet Speak";
20+
this.module = "Default";
21+
this.description = "Converts to and from Leet Speak";
22+
this.infoURL = "https://wikipedia.org/wiki/Leet";
23+
this.inputType = "string";
24+
this.outputType = "string";
25+
this.args = [
26+
{
27+
name: "Direction",
28+
type: "option",
29+
value: ["To Leet Speak", "From Leet Speak"],
30+
defaultIndex: 0
31+
}
32+
];
33+
}
34+
35+
/**
36+
* @param {string} input
37+
* @param {Object[]} args
38+
* @returns {string}
39+
*/
40+
run(input, args) {
41+
const direction = args[0];
42+
if (direction === "To Leet Speak") {
43+
return input.replace(/[abcdefghijklmnopqrstuvwxyz]/gi, char => {
44+
return toLeetMap[char.toLowerCase()] || char;
45+
});
46+
} else if (direction === "From Leet Speak") {
47+
return input.replace(/[48cd3f6h1jklmn0pqr57uvwxyz]/g, char => {
48+
return fromLeetMap[char] || char;
49+
});
50+
}
51+
}
52+
}
53+
54+
const toLeetMap = {
55+
"a": "4",
56+
"b": "b",
57+
"c": "c",
58+
"d": "d",
59+
"e": "3",
60+
"f": "f",
61+
"g": "g",
62+
"h": "h",
63+
"i": "1",
64+
"j": "j",
65+
"k": "k",
66+
"l": "l",
67+
"m": "m",
68+
"n": "n",
69+
"o": "0",
70+
"p": "p",
71+
"q": "q",
72+
"r": "r",
73+
"s": "5",
74+
"t": "7",
75+
"u": "u",
76+
"v": "v",
77+
"w": "w",
78+
"x": "x",
79+
"y": "y",
80+
"z": "z"
81+
};
82+
83+
const fromLeetMap = {
84+
"4": "a",
85+
"b": "b",
86+
"c": "c",
87+
"d": "d",
88+
"3": "e",
89+
"f": "f",
90+
"g": "g",
91+
"h": "h",
92+
"1": "i",
93+
"j": "j",
94+
"k": "k",
95+
"l": "l",
96+
"m": "m",
97+
"n": "n",
98+
"0": "o",
99+
"p": "p",
100+
"q": "q",
101+
"r": "r",
102+
"5": "s",
103+
"7": "t",
104+
"u": "u",
105+
"v": "v",
106+
"w": "w",
107+
"x": "x",
108+
"y": "y",
109+
"z": "z"
110+
};
111+
112+
export default ConvertLeetSpeak;
113+

‎tests/operations/index.mjs

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import "./tests/Comment.mjs";
5454
import "./tests/Compress.mjs";
5555
import "./tests/ConditionalJump.mjs";
5656
import "./tests/ConvertCoordinateFormat.mjs";
57+
import "./tests/ConvertLeetSpeak.mjs";
5758
import "./tests/ConvertToNATOAlphabet.mjs";
5859
import "./tests/Crypt.mjs";
5960
import "./tests/CSV.mjs";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* @author bartblaze []
3+
* @copyright Crown Copyright 2025
4+
* @license Apache-2.0
5+
*/
6+
7+
import TestRegister from "../../lib/TestRegister.mjs";
8+
9+
TestRegister.addTests([
10+
{
11+
name: "Convert to Leet Speak: basic text",
12+
input: "leet",
13+
expectedOutput: "l337",
14+
recipeConfig: [
15+
{
16+
op: "Convert Leet Speak",
17+
args: ["To Leet Speak"]
18+
}
19+
]
20+
},
21+
{
22+
name: "Convert from Leet Speak: basic leet",
23+
input: "l337",
24+
expectedOutput: "leet",
25+
recipeConfig: [
26+
{
27+
op: "Convert Leet Speak",
28+
args: ["From Leet Speak"]
29+
}
30+
]
31+
}
32+
]);
33+

0 commit comments

Comments
 (0)
Please sign in to comment.