passweird 0.2.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e6d59497282552bfae629eb27790ab7052889936ed6cfe37b84ae34c308de1f
4
- data.tar.gz: 79040059aad66e4eb6afaf2e6186b00017aeeed6697658960d7388768dc77f85
3
+ metadata.gz: 3371f14ef5f297596e1afdf26d839efbd8f33cc35d59e9839148cf855253abbf
4
+ data.tar.gz: eba853d58d7a7809847cd0f73255fe3840dff4824c44f5bb354c9f0d523e09ba
5
5
  SHA512:
6
- metadata.gz: fdef30ff3536b8fcf72d9cbc2cca93793c2ac4a2802726e3c094d1c6b97ed7d35201dc392d9b4598d329aa31fe9240f84549975ef59cb1818ae95192072d8d20
7
- data.tar.gz: ac5988d41745ce56cb3f071c104e2baa94b5adc0b0044f2188e8b3dd50c85b852af0e309149e66245f5d21d0ca0706b5f8466291c8654339ec6d14e4bfe26182
6
+ metadata.gz: 2f04f396b18591510a151cfed0343c66ef4966cd2922a34d354b1e7a86d57907c24a175d5bc14e8e17758851356ef55b82473334365d924b4be0fce4bdd03e64
7
+ data.tar.gz: 1f06e33d0d21e8aff91c01a6de136002553d396d5a927db9abfae52bf6afdc10e139213faddb860f1c5e0f2181df964bfb567ac78df06e6cbe149e7c08d242d6
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- passweird (0.2.1)
4
+ passweird (1.0.0)
5
5
  activerecord (>= 7.0, < 8.0)
6
6
 
7
7
  GEM
@@ -38,17 +38,17 @@ module Passweird
38
38
  #
39
39
  # @return [Array<String>] an array of unique possible terms
40
40
  def possible_terms
41
- ([password] + substrings + unleeted_substrings).uniq
41
+ @possible_terms ||= (substrings + unleeted_substrings).map(&:downcase).uniq
42
42
  end
43
43
 
44
44
  private
45
45
 
46
46
  def substrings
47
- @substrings ||= Substringer.substrings(password.downcase)
47
+ @substrings ||= Substringer.substrings(password)
48
48
  end
49
49
 
50
50
  def unleeted_substrings
51
- @unleeted_substrings ||= LeetSpeak.unleet_all(substrings)
51
+ @unleeted_substrings ||= Leet::Translate.unleet_all(substrings)
52
52
  end
53
53
  end
54
54
  end
@@ -0,0 +1,930 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Passweird
4
+ module Leet
5
+ # This contains cipher to better translate leet with multiple adjacent I's and L's
6
+ # These equivalents are proccessed through N-gram analysis of
7
+ # english words from http://wordlist.aspell.net/.
8
+ # Explanation: Preprocessed cipher was considered vs deciphering using N-gram logic
9
+ # in favor of speed and less complexity
10
+ class ExtendedCipher # rubocop:disable Metrics/ClassLength
11
+ CIPHER = {
12
+ "M1111117" => "MILLILIT",
13
+ "M11111U" => "MILLILU",
14
+ "W11115" => "WILLIS",
15
+ "41111K" => "AILLIK",
16
+ "P11117" => "PILLIT",
17
+ "K11110" => "KILLIO",
18
+ "H11114" => "HILLIA",
19
+ "11111P" => "LILLIP",
20
+ "411115" => "AILLIS",
21
+ "P1111F" => "PILLIF",
22
+ "41111N" => "AILLIN",
23
+ "R11110" => "RILLIO",
24
+ "V11117" => "VILLIT",
25
+ "(1111U" => "CILLIU",
26
+ "H1111D" => "HILLID",
27
+ "K11116" => "KILLIG",
28
+ "(11117" => "CILLIT",
29
+ "(11114" => "CILLIA",
30
+ "(11110" => "CILLIO",
31
+ "K1111N" => "KILLIN",
32
+ "K1111K" => "KILLIK",
33
+ "K11113" => "KILLIE",
34
+ "K1111(" => "KILLIC",
35
+ "711113" => "TILLIE",
36
+ "411110" => "ALILLO",
37
+ "M11117" => "MILLIT",
38
+ "U1111N" => "UILLIN",
39
+ "X1111F" => "XILLIF",
40
+ "D1111D" => "DILLID",
41
+ "R1111F" => "RILLIF",
42
+ "311114" => "ELILLA",
43
+ "H11115" => "HILLIS",
44
+ "M1111W" => "MILLIW",
45
+ "611117" => "GILLIT",
46
+ "W1111Y" => "WILILY",
47
+ "V11113" => "VILLIE",
48
+ "311110" => "ELILIO",
49
+ "31111N" => "EILLIN",
50
+ "71111D" => "TILLID",
51
+ "U11117" => "UILLIT",
52
+ "U1111D" => "UILLID",
53
+ "U11115" => "UILLIS",
54
+ "N1111(" => "NILLIC",
55
+ "511118" => "SILLIB",
56
+ "M11115" => "MILLIS",
57
+ "M1111R" => "MILLIR",
58
+ "M1111P" => "MILLIP",
59
+ "011114" => "OLILLA",
60
+ "W11117" => "WILLIT",
61
+ "M11110" => "MILLIO",
62
+ "M1111N" => "MILLIN",
63
+ "V1111F" => "VILLIF",
64
+ "H1111N" => "HILLIN",
65
+ "V11114" => "VILLIA",
66
+ "M1111M" => "MILLIM",
67
+ "H1111K" => "HILLIK",
68
+ "01111Y" => "OLLILY",
69
+ "811114" => "BILLIA",
70
+ "M1111H" => "MILLIH",
71
+ "R11115" => "RILLIS",
72
+ "M11116" => "MILLIG",
73
+ "31111F" => "ELILIF",
74
+ "U11110" => "ULLILO",
75
+ "M11113" => "MILLIE",
76
+ "W11113" => "WILLIE",
77
+ "M1111(" => "MILLIC",
78
+ "711117" => "TILLIT",
79
+ "811110" => "BILLIO",
80
+ "M11114" => "MILLIA",
81
+ "611114" => "GILLIA",
82
+ "D11113" => "DILLIE",
83
+ "D11110" => "DILLIO",
84
+ "711115" => "TILLIS",
85
+ "W11114" => "WILLIA",
86
+ "H11113" => "HILLIE",
87
+ "611115" => "GILLIS",
88
+ "R1111U" => "RILLIU",
89
+ "U11112" => "UILLIZ",
90
+ "V1111(" => "VILLIC",
91
+ "R1111N" => "RILLIN",
92
+ "411113" => "AILLIE",
93
+ "611110" => "GILLIO",
94
+ "611113" => "GILLIE",
95
+ "411114" => "AILLIA",
96
+ "(1111N" => "CILLIN",
97
+ "W1111W" => "WILLIW",
98
+ "111118" => "LILLIB",
99
+ "P11110" => "PILLIO",
100
+ "F1111N" => "FILLIN",
101
+ "P1111(" => "PILLIC",
102
+ "711110" => "TILLIO",
103
+ "V1111N" => "VILLIN",
104
+ "(1111F" => "CILLIF",
105
+ "(1111(" => "CILLIC",
106
+ "61111N" => "GILLIN",
107
+ "61111F" => "GILLIF",
108
+ "61111D" => "GILLID",
109
+ "R11113" => "RILLIE",
110
+ "H1111P" => "HILLIP",
111
+ "H11118" => "HILLIB",
112
+ "71111(" => "TILLIC",
113
+ "81111N" => "BILLIN",
114
+ "W1111N" => "WILLIN",
115
+ "311117" => "ELILIT",
116
+ "V11110" => "VILLIO",
117
+ "811113" => "BILLIE",
118
+ "71111F" => "TILLIF",
119
+ "M1111V" => "MILLIV",
120
+ "F1111P" => "FILLIP",
121
+ "D1111N" => "DILLIN",
122
+ "P1111N" => "PILLIN",
123
+ "R11117" => "RILLIT",
124
+ "N11110" => "NILLIO",
125
+ "X1111P" => "XILLIP",
126
+ "V11115" => "VILLIS",
127
+ "511117" => "SILLIT",
128
+ "211110" => "ZILLIO",
129
+ "M1111F" => "MILLIF",
130
+ "511113" => "SILLIE",
131
+ "M11118" => "MILLIB",
132
+ "71111N" => "TILLIN",
133
+ "N1111N" => "NILLIN",
134
+ "(1111D" => "CILLID",
135
+ "D11115" => "DILLIS",
136
+ "R11114" => "RILLIA",
137
+ "31110" => "ELLIO",
138
+ "U111N" => "ULLIN",
139
+ "11117" => "ILLIT",
140
+ "71113" => "TILLE",
141
+ "P111U" => "PILLU",
142
+ "Y1113" => "YLLIE",
143
+ "7111F" => "TILIF",
144
+ "71118" => "TILIB",
145
+ "R1114" => "RILLA",
146
+ "F1118" => "FILIB",
147
+ "W111K" => "WLLIK",
148
+ "01115" => "OLLIS",
149
+ "81118" => "BILLB",
150
+ "81110" => "BILIO",
151
+ "W1116" => "WILIG",
152
+ "Y1117" => "YLLIT",
153
+ "6111R" => "GILLR",
154
+ "4111K" => "ALLIK",
155
+ "N1117" => "NILIT",
156
+ "N111N" => "NILIN",
157
+ "V1112" => "VILIZ",
158
+ "41118" => "ALLIB",
159
+ "6111M" => "GILLM",
160
+ "W111N" => "WILIN",
161
+ "8111U" => "BILIU",
162
+ "H111H" => "HILLH",
163
+ "Y111N" => "YLLIN",
164
+ "M1118" => "MILLB",
165
+ "Y111D" => "YLLID",
166
+ "4111U" => "ALLIU",
167
+ "41117" => "ALLIT",
168
+ "41116" => "ALLIG",
169
+ "U111P" => "ULLIP",
170
+ "U111F" => "ULLIF",
171
+ "F111F" => "FILIF",
172
+ "0111X" => "OLLIX",
173
+ "U111Y" => "UILLY",
174
+ "31113" => "ELLIE",
175
+ "D1115" => "DILLS",
176
+ "U1113" => "UILLE",
177
+ "61117" => "GILIT",
178
+ "F1114" => "FILIA",
179
+ "41113" => "ALLIE",
180
+ "N1115" => "NILIS",
181
+ "(111U" => "CILLU",
182
+ "(1110" => "CILLO",
183
+ "(1111" => "CILLI",
184
+ "(111F" => "CILIF",
185
+ "H111(" => "HILIC",
186
+ "N111D" => "NILID",
187
+ "P111F" => "PILIF",
188
+ "U1116" => "ULLIG",
189
+ "H111R" => "HILLR",
190
+ "4111H" => "ALLIH",
191
+ "K1113" => "KILLE",
192
+ "N111F" => "NILIF",
193
+ "N1114" => "NILLA",
194
+ "M111U" => "MILLU",
195
+ "U1117" => "ULLIT",
196
+ "M111W" => "MILLW",
197
+ "M111R" => "MILLR",
198
+ "M1110" => "MILIO",
199
+ "U1115" => "ULLIS",
200
+ "R1113" => "RILLE",
201
+ "01110" => "OLILO",
202
+ "M1115" => "MILLS",
203
+ "H1113" => "HILLE",
204
+ "P1110" => "PILLO",
205
+ "(1113" => "CILLE",
206
+ "H1114" => "HILIA",
207
+ "M111(" => "MILIC",
208
+ "11118" => "ILLIB",
209
+ "P1116" => "PILIG",
210
+ "H1110" => "HILLO",
211
+ "4111M" => "ALLIM",
212
+ "4111(" => "ALLIC",
213
+ "51115" => "SILIS",
214
+ "F1115" => "FILLS",
215
+ "V111U" => "VILLU",
216
+ "31115" => "ELLIS",
217
+ "5111U" => "SILLU",
218
+ "V1110" => "VILLO",
219
+ "71115" => "TILIS",
220
+ "R1115" => "RILIS",
221
+ "M1117" => "MILIT",
222
+ "V1115" => "VILIS",
223
+ "V1113" => "VILLE",
224
+ "V1111" => "VILLI",
225
+ "(1114" => "CILLA",
226
+ "Y111(" => "YLLIC",
227
+ "3111V" => "ELLIV",
228
+ "71117" => "TILIT",
229
+ "0111Y" => "OLILY",
230
+ "61110" => "GILLO",
231
+ "21117" => "ZILIT",
232
+ "M111N" => "MILIN",
233
+ "41115" => "ALLIS",
234
+ "X111U" => "XILLU",
235
+ "X1110" => "XILLO",
236
+ "R111N" => "RILIN",
237
+ "N111Y" => "NLILY",
238
+ "5111(" => "SILIC",
239
+ "31117" => "ELLIT",
240
+ "H1112" => "HILIZ",
241
+ "D111N" => "DILIN",
242
+ "81117" => "BILIT",
243
+ "P1115" => "PILLS",
244
+ "3111N" => "ELLIN",
245
+ "V1114" => "VILLA",
246
+ "11113" => "LILIE",
247
+ "P1111" => "PILLI",
248
+ "3111R" => "ELLIR",
249
+ "41114" => "ALLIA",
250
+ "J1110" => "JILLO",
251
+ "U111(" => "ULLIC",
252
+ "K111Y" => "KILLY",
253
+ "K1110" => "KILLO",
254
+ "K111D" => "KILLD",
255
+ "K111(" => "KILLC",
256
+ "K1114" => "KILLA",
257
+ "K111M" => "KILIM",
258
+ "5111D" => "SILID",
259
+ "J1115" => "JILLS",
260
+ "J1113" => "JILLE",
261
+ "J1114" => "JILLA",
262
+ "3111K" => "ELLIK",
263
+ "71112" => "TILIZ",
264
+ "N111(" => "NILIC",
265
+ "11115" => "ILLIS",
266
+ "1111Q" => "ILLIQ",
267
+ "1111P" => "ILLIP",
268
+ "1111N" => "ILLIN",
269
+ "1111M" => "ILLIM",
270
+ "1111(" => "ILLIC",
271
+ "U111U" => "UILLU",
272
+ "P111N" => "PILIN",
273
+ "U1118" => "UILIB",
274
+ "Y1115" => "YLLIS",
275
+ "(111N" => "CILIN",
276
+ "H111W" => "HILLW",
277
+ "H111M" => "HILLM",
278
+ "H111F" => "HILLF",
279
+ "71116" => "TILIG",
280
+ "(1112" => "CILIZ",
281
+ "P1112" => "PILIZ",
282
+ "H1111" => "HILLI",
283
+ "U111D" => "ULLID",
284
+ "W111Y" => "WILLY",
285
+ "W1115" => "WILLS",
286
+ "W1113" => "WILLE",
287
+ "4111R" => "ALLIR",
288
+ "0111W" => "OLLIW",
289
+ "V111Y" => "VILLY",
290
+ "N1112" => "NILIZ",
291
+ "U1112" => "UILIZ",
292
+ "6111Y" => "GILLY",
293
+ "6111N" => "GILLN",
294
+ "6111F" => "GILLF",
295
+ "61113" => "GILLE",
296
+ "(1117" => "CILIT",
297
+ "7111(" => "TILIC",
298
+ "W111M" => "WILLM",
299
+ "M1112" => "MILIZ",
300
+ "4111W" => "ALLIW",
301
+ "4111V" => "ALLIV",
302
+ "41110" => "ALLIO",
303
+ "M111Y" => "MILLY",
304
+ "51114" => "SILLA",
305
+ "31112" => "ELLIZ",
306
+ "F111M" => "FILLM",
307
+ "51112" => "SILIZ",
308
+ "41112" => "ALLIZ",
309
+ "M111P" => "MILLP",
310
+ "P111P" => "PILIP",
311
+ "51117" => "SILIT",
312
+ "K1115" => "KILLS",
313
+ "M111M" => "MILLM",
314
+ "F111P" => "FILIP",
315
+ "F1110" => "FILIO",
316
+ "F1116" => "FILIG",
317
+ "F111(" => "FILIC",
318
+ "81115" => "BILIS",
319
+ "R1117" => "RILIT",
320
+ "X1117" => "XILIT",
321
+ "21114" => "ZILLA",
322
+ "P111M" => "PILIM",
323
+ "M111H" => "MILLH",
324
+ "01117" => "OLLIT",
325
+ "01114" => "OILIA",
326
+ "M111D" => "MILLD",
327
+ "W111F" => "WILLF",
328
+ "D1116" => "DILIG",
329
+ "V111P" => "VILIP",
330
+ "V111F" => "VILIF",
331
+ "R1112" => "RILIZ",
332
+ "4111N" => "ALLIN",
333
+ "1111Y" => "LILLY",
334
+ "F111N" => "FILIN",
335
+ "0111N" => "OLLIN",
336
+ "D111Y" => "DILLY",
337
+ "V111N" => "VILIN",
338
+ "D1117" => "DILIT",
339
+ "M1113" => "MILLE",
340
+ "31114" => "ELLIA",
341
+ "81112" => "BILIZ",
342
+ "R111(" => "RILIC",
343
+ "7111D" => "TILID",
344
+ "0111F" => "OLLIF",
345
+ "U1114" => "UILLA",
346
+ "51113" => "SILIE",
347
+ "3111Y" => "ELILY",
348
+ "0111Q" => "OLLIQ",
349
+ "0111M" => "OLLIM",
350
+ "01116" => "OLLIG",
351
+ "01113" => "OLLIE",
352
+ "0111(" => "OLLIC",
353
+ "11110" => "LILIO",
354
+ "D1113" => "DILLE",
355
+ "N111U" => "NILLU",
356
+ "5111F" => "SILIF",
357
+ "8111(" => "BILIC",
358
+ "W1111" => "WILLI",
359
+ "0111U" => "OLLIU",
360
+ "(1115" => "CILIS",
361
+ "(111(" => "CILIC",
362
+ "N1110" => "NILLO",
363
+ "3111D" => "ELLID",
364
+ "H1117" => "HILIT",
365
+ "F1113" => "FILLE",
366
+ "H111U" => "HILLU",
367
+ "H111N" => "HILIN",
368
+ "H111D" => "HILID",
369
+ "H1118" => "HILIB",
370
+ "N1113" => "NILLE",
371
+ "W1117" => "WILLT",
372
+ "3111F" => "ELLIF",
373
+ "D1114" => "DILLA",
374
+ "0111D" => "OLLID",
375
+ "D1110" => "DILLO",
376
+ "7111N" => "TILIN",
377
+ "P1114" => "PILLA",
378
+ "71114" => "TILLA",
379
+ "4111P" => "ALLIP",
380
+ "4111D" => "ALLID",
381
+ "7111Y" => "TILLY",
382
+ "H111Y" => "HILLY",
383
+ "R111Y" => "RILLY",
384
+ "K111W" => "KILIW",
385
+ "7111R" => "TILIR",
386
+ "7111M" => "TILLM",
387
+ "K111J" => "KILLJ",
388
+ "P1117" => "PILIT",
389
+ "P111K" => "PILIK",
390
+ "7111K" => "TILIK",
391
+ "U111K" => "ULLIK",
392
+ "W1114" => "WILLA",
393
+ "5111N" => "SILIN",
394
+ "K111F" => "KILLF",
395
+ "U1110" => "ULLIO",
396
+ "5111Y" => "SILLY",
397
+ "51110" => "SILLO",
398
+ "5111Q" => "SILIQ",
399
+ "V1117" => "VILIT",
400
+ "M111Q" => "MILIQ",
401
+ "8111F" => "BILIF",
402
+ "D111U" => "DILLU",
403
+ "1111U" => "LILIU",
404
+ "11114" => "LILIA",
405
+ "R111M" => "RILLM",
406
+ "8111Y" => "BILLY",
407
+ "8111P" => "BILLP",
408
+ "8111H" => "BILLH",
409
+ "81113" => "BILLE",
410
+ "8111V" => "BILIV",
411
+ "8111R" => "BILIR",
412
+ "8111N" => "BILIN",
413
+ "8111M" => "BILIM",
414
+ "7111U" => "TILLU",
415
+ "3111U" => "EILLU",
416
+ "4111Y" => "AILLY",
417
+ "M111F" => "MILLF",
418
+ "U111W" => "UILLW",
419
+ "Y111U" => "YLLIU",
420
+ "Y1110" => "YLLIO",
421
+ "Y1114" => "YLLIA",
422
+ "71110" => "TILLO",
423
+ "U111M" => "UILLM",
424
+ "31116" => "ELLIG",
425
+ "3111(" => "ELLIC",
426
+ "31118" => "ELLIB",
427
+ "W1110" => "WILLO",
428
+ "0111P" => "OLLIP",
429
+ "W1118" => "WILLB",
430
+ "7111W" => "TILLW",
431
+ "X111(" => "XILIC",
432
+ "P111D" => "PILID",
433
+ "3111M" => "ELLIM",
434
+ "U111V" => "ULLIV",
435
+ "P1118" => "PILLB",
436
+ "P111W" => "PILLW",
437
+ "41111" => "ALILI",
438
+ "4111F" => "ALLIF",
439
+ "X111N" => "XILIN",
440
+ "X1114" => "XILLA",
441
+ "81114" => "BILIA",
442
+ "6111U" => "GILLU",
443
+ "61115" => "GILIS",
444
+ "61111" => "GILLI",
445
+ "61114" => "GILLA",
446
+ "H111P" => "HILIP",
447
+ "P1113" => "PILLE",
448
+ "R111K" => "RLLIK",
449
+ "H1115" => "HILIS",
450
+ "R111U" => "RILLU",
451
+ "R1110" => "RILLO",
452
+ "3111P" => "ELLIP",
453
+ "0111K" => "OLLIK",
454
+ "M1114" => "MILIA",
455
+ "W111P" => "WILLP",
456
+ "R1118" => "RILLB",
457
+ "R111F" => "RILIF",
458
+ "411Y" => "ALLY",
459
+ "2110" => "ZILO",
460
+ "M11M" => "MILM",
461
+ "M118" => "MILB",
462
+ "1115" => "ILIS",
463
+ "M11Q" => "MILQ",
464
+ "W11V" => "WLIV",
465
+ "211P" => "ZILP",
466
+ "W11M" => "WILM",
467
+ "P11P" => "PILP",
468
+ "(11W" => "CILW",
469
+ "(11R" => "CILR",
470
+ "7116" => "TLIG",
471
+ "M11W" => "MILW",
472
+ "H112" => "HLIZ",
473
+ "K11U" => "KILU",
474
+ "K118" => "KILB",
475
+ "K114" => "KILA",
476
+ "1116" => "ILLG",
477
+ "H118" => "HILB",
478
+ "(11U" => "CILU",
479
+ "811F" => "BIIF",
480
+ "611V" => "GILV",
481
+ "511F" => "SLIF",
482
+ "F11D" => "FLID",
483
+ "V11P" => "VILP",
484
+ "D11(" => "DLIC",
485
+ "311J" => "ELIJ",
486
+ "V11H" => "VILH",
487
+ "X11D" => "XIID",
488
+ "0111" => "OLLI",
489
+ "D116" => "DLIG",
490
+ "511W" => "SLIW",
491
+ "K11D" => "KILD",
492
+ "R11U" => "RILU",
493
+ "P11Q" => "PLIQ",
494
+ "U111" => "ULLI",
495
+ "P112" => "PLIZ",
496
+ "X111" => "XIII",
497
+ "Y112" => "YLIZ",
498
+ "R112" => "RLIZ",
499
+ "W118" => "WILB",
500
+ "N11H" => "NLIH",
501
+ "511R" => "SILR",
502
+ "211(" => "ZILC",
503
+ "2114" => "ZILA",
504
+ "X11N" => "XLIN",
505
+ "W11(" => "WILC",
506
+ "V111" => "VIII",
507
+ "V114" => "VILA",
508
+ "X115" => "XILS",
509
+ "5118" => "SLIB",
510
+ "N11D" => "NIID",
511
+ "W117" => "WILT",
512
+ "811U" => "BILU",
513
+ "711P" => "TLIP",
514
+ "U11X" => "ULIX",
515
+ "011Q" => "OLIQ",
516
+ "511U" => "SILU",
517
+ "5117" => "SLIT",
518
+ "511H" => "SILH",
519
+ "M11H" => "MLIH",
520
+ "D11P" => "DLIP",
521
+ "H11M" => "HLIM",
522
+ "H11(" => "HLIC",
523
+ "411X" => "ALIX",
524
+ "D118" => "DLIB",
525
+ "K11M" => "KLIM",
526
+ "U11K" => "ULIK",
527
+ "R11F" => "RLIF",
528
+ "7117" => "TILT",
529
+ "Y111" => "YLLI",
530
+ "N11U" => "NILU",
531
+ "P11U" => "PILU",
532
+ "D111" => "DILL",
533
+ "H11H" => "HILH",
534
+ "W115" => "WILS",
535
+ "W11Y" => "WILY",
536
+ "R11V" => "RLIV",
537
+ "W111" => "WILL",
538
+ "711V" => "TLIV",
539
+ "011W" => "OLLW",
540
+ "811Q" => "BLIQ",
541
+ "(11D" => "CLID",
542
+ "N117" => "NLIT",
543
+ "N11Q" => "NLIQ",
544
+ "N11M" => "NLIM",
545
+ "N11F" => "NIIF",
546
+ "N11(" => "NLIC",
547
+ "N118" => "NLIB",
548
+ "N11P" => "NILP",
549
+ "N111" => "NILI",
550
+ "U11U" => "ULLU",
551
+ "5111" => "SILL",
552
+ "M11V" => "MILV",
553
+ "M11R" => "MILR",
554
+ "M11P" => "MILP",
555
+ "M110" => "MILO",
556
+ "M11F" => "MILF",
557
+ "M11(" => "MILC",
558
+ "(112" => "CLIZ",
559
+ "J115" => "JLIS",
560
+ "W11H" => "WILH",
561
+ "W116" => "WLIG",
562
+ "W11F" => "WILF",
563
+ "411Q" => "ALIQ",
564
+ "R117" => "RLIT",
565
+ "K117" => "KILT",
566
+ "K11P" => "KLIP",
567
+ "K110" => "KILO",
568
+ "D117" => "DLIT",
569
+ "J111" => "JILL",
570
+ "J117" => "JILT",
571
+ "211K" => "ZLIK",
572
+ "4111" => "ALLI",
573
+ "R118" => "RLIB",
574
+ "711M" => "TLIM",
575
+ "R11M" => "RLIM",
576
+ "111Y" => "ILLY",
577
+ "1117" => "LILT",
578
+ "1118" => "LILB",
579
+ "111(" => "ILIC",
580
+ "1114" => "ILLA",
581
+ "H11U" => "HILU",
582
+ "H117" => "HILT",
583
+ "H11V" => "HILV",
584
+ "H11F" => "HILF",
585
+ "D115" => "DLIS",
586
+ "011K" => "OLIK",
587
+ "V11Y" => "VILY",
588
+ "D110" => "DILO",
589
+ "D11H" => "DLIH",
590
+ "6118" => "GILB",
591
+ "611M" => "GLIM",
592
+ "6117" => "GLIT",
593
+ "611R" => "GILR",
594
+ "611P" => "GILP",
595
+ "711H" => "TILH",
596
+ "R11(" => "RLIC",
597
+ "711U" => "TILU",
598
+ "U112" => "ULIZ",
599
+ "711(" => "TLIC",
600
+ "F11X" => "FLIX",
601
+ "F11V" => "FLIV",
602
+ "F116" => "FLIG",
603
+ "F118" => "FILB",
604
+ "K111" => "KILL",
605
+ "F110" => "FILO",
606
+ "F11F" => "FILF",
607
+ "X114" => "XILA",
608
+ "3112" => "ELIZ",
609
+ "N11V" => "NLIV",
610
+ "N115" => "NLIS",
611
+ "6110" => "GLIO",
612
+ "311W" => "ELLW",
613
+ "H11P" => "HLIP",
614
+ "(110" => "CILO",
615
+ "011H" => "OLLH",
616
+ "(11K" => "CLIK",
617
+ "D11D" => "DIID",
618
+ "V11W" => "VILW",
619
+ "V11F" => "VILF",
620
+ "V11D" => "VILD",
621
+ "M11U" => "MILU",
622
+ "311R" => "ELIR",
623
+ "V11R" => "VILR",
624
+ "M11N" => "MLIN",
625
+ "P11K" => "PLIK",
626
+ "R11D" => "RIID",
627
+ "7111" => "TILL",
628
+ "0118" => "OLIB",
629
+ "811Y" => "BILY",
630
+ "611Y" => "GILY",
631
+ "(117" => "CLIT",
632
+ "K113" => "KLIE",
633
+ "M117" => "MILT",
634
+ "(111" => "CILL",
635
+ "(114" => "CILA",
636
+ "Y11F" => "YLIF",
637
+ "(11Y" => "CILY",
638
+ "V110" => "VILO",
639
+ "F11K" => "FLIK",
640
+ "P11Y" => "PILY",
641
+ "U11W" => "ULLW",
642
+ "U11R" => "ULLR",
643
+ "U11P" => "ULIP",
644
+ "U11H" => "ULLH",
645
+ "U116" => "ULIG",
646
+ "U11F" => "ULIF",
647
+ "U118" => "ULLB",
648
+ "U11M" => "ULIM",
649
+ "Y11U" => "YLLU",
650
+ "D114" => "DILA",
651
+ "2113" => "ZLIE",
652
+ "W113" => "WLIE",
653
+ "H11N" => "HLIN",
654
+ "Y113" => "YLIE",
655
+ "Y114" => "YLLA",
656
+ "X11Y" => "XILY",
657
+ "W11K" => "WLIK",
658
+ "N11Y" => "NILY",
659
+ "011X" => "OLIX",
660
+ "011V" => "OLIV",
661
+ "711F" => "TLIF",
662
+ "211Y" => "ZILY",
663
+ "511Y" => "SILY",
664
+ "8112" => "BLIZ",
665
+ "811V" => "BLIV",
666
+ "8117" => "BLIT",
667
+ "811P" => "BLIP",
668
+ "R11K" => "RLIK",
669
+ "D11M" => "DLIM",
670
+ "D11F" => "DLIF",
671
+ "011D" => "OLID",
672
+ "811H" => "BILH",
673
+ "8118" => "BILB",
674
+ "F114" => "FILA",
675
+ "8110" => "BLIO",
676
+ "811K" => "BLIK",
677
+ "Y11D" => "YLID",
678
+ "311P" => "ELIP",
679
+ "311H" => "ELLH",
680
+ "3118" => "ELIB",
681
+ "311V" => "ELIV",
682
+ "311Q" => "ELIQ",
683
+ "611D" => "GILD",
684
+ "F11Y" => "FILY",
685
+ "V11M" => "VILM",
686
+ "K11K" => "KLIK",
687
+ "D11K" => "DLIK",
688
+ "5115" => "SILS",
689
+ "5114" => "SILA",
690
+ "H11K" => "HLIK",
691
+ "K11(" => "KLIC",
692
+ "611K" => "GLIK",
693
+ "K115" => "KLIS",
694
+ "K116" => "KLIG",
695
+ "Y11K" => "YLIK",
696
+ "X11K" => "XLIK",
697
+ "6111" => "GILL",
698
+ "M115" => "MILS",
699
+ "711D" => "TIID",
700
+ "7115" => "TILS",
701
+ "P117" => "PLIT",
702
+ "Y11Y" => "YLLY",
703
+ "V117" => "VILT",
704
+ "M11Y" => "MILY",
705
+ "N114" => "NILA",
706
+ "311X" => "ELIX",
707
+ "811D" => "BIID",
708
+ "311D" => "ELID",
709
+ "H115" => "HILS",
710
+ "6115" => "GLIS",
711
+ "611F" => "GLIF",
712
+ "U110" => "ULLO",
713
+ "P11D" => "PIID",
714
+ "8114" => "BILA",
715
+ "411H" => "ALLH",
716
+ "411V" => "ALIV",
717
+ "411P" => "ALIP",
718
+ "411M" => "ALIM",
719
+ "2115" => "ZIIS",
720
+ "N11K" => "NLIK",
721
+ "3111" => "ELLI",
722
+ "511N" => "SLIN",
723
+ "6114" => "GLIA",
724
+ "R116" => "RLIG",
725
+ "0112" => "OLIZ",
726
+ "711K" => "TLIK",
727
+ "311K" => "ELIK",
728
+ "8111" => "BILL",
729
+ "Y11(" => "YLIC",
730
+ "(11V" => "CLIV",
731
+ "7114" => "TILA",
732
+ "H11Y" => "HILY",
733
+ "7110" => "TILO",
734
+ "X113" => "XILE",
735
+ "F115" => "FILS",
736
+ "F11R" => "FLIR",
737
+ "F111" => "FILL",
738
+ "N11N" => "NLIN",
739
+ "311F" => "ELIF",
740
+ "K11F" => "KILF",
741
+ "4112" => "ALIZ",
742
+ "V11N" => "VILN",
743
+ "Y110" => "YLLO",
744
+ "811M" => "BLIM",
745
+ "Y115" => "YLIS",
746
+ "N110" => "NILO",
747
+ "5110" => "SILO",
748
+ "U11(" => "ULIC",
749
+ "Y117" => "YLIT",
750
+ "P116" => "PILG",
751
+ "U114" => "ULLA",
752
+ "R115" => "RLIS",
753
+ "011M" => "OLIM",
754
+ "0116" => "OLIG",
755
+ "R11P" => "RLIP",
756
+ "D11U" => "DILU",
757
+ "U115" => "ULIS",
758
+ "7118" => "TILB",
759
+ "611(" => "GLIC",
760
+ "011P" => "OLIP",
761
+ "W11D" => "WILD",
762
+ "R110" => "RILO",
763
+ "K11N" => "KLIN",
764
+ "R113" => "RLIE",
765
+ "D11Y" => "DILY",
766
+ "511P" => "SLIP",
767
+ "511M" => "SLIM",
768
+ "5116" => "SLIG",
769
+ "511D" => "SLID",
770
+ "511(" => "SLIC",
771
+ "511V" => "SILV",
772
+ "U11N" => "ULIN",
773
+ "U11D" => "UILD",
774
+ "411W" => "AILW",
775
+ "411R" => "AILR",
776
+ "411F" => "ALIF",
777
+ "211N" => "ZLIN",
778
+ "Y11N" => "YLIN",
779
+ "W11N" => "WLIN",
780
+ "P11N" => "PLIN",
781
+ "(115" => "CLIS",
782
+ "011N" => "OLIN",
783
+ "F11(" => "FLIC",
784
+ "P11M" => "PLIM",
785
+ "P113" => "PILE",
786
+ "P114" => "PILA",
787
+ "0114" => "OLLA",
788
+ "(11Q" => "CLIQ",
789
+ "(11P" => "CLIP",
790
+ "(11N" => "CLIN",
791
+ "(11M" => "CLIM",
792
+ "(11F" => "CLIF",
793
+ "(113" => "CILE",
794
+ "(11(" => "CLIC",
795
+ "H11D" => "HILD",
796
+ "3110" => "ELLO",
797
+ "311U" => "ELLU",
798
+ "4117" => "ALIT",
799
+ "U113" => "ULLE",
800
+ "R11N" => "RLIN",
801
+ "0113" => "OLLE",
802
+ "8115" => "BLIS",
803
+ "811(" => "BLIC",
804
+ "3115" => "ELIS",
805
+ "3113" => "ELLE",
806
+ "4115" => "ALIS",
807
+ "F11N" => "FLIN",
808
+ "U11Y" => "ULLY",
809
+ "8113" => "BILE",
810
+ "811N" => "BLIN",
811
+ "R11Y" => "RILY",
812
+ "P11(" => "PLIC",
813
+ "411N" => "ALIN",
814
+ "P11F" => "PLIF",
815
+ "4110" => "ALLO",
816
+ "411K" => "ALIK",
817
+ "4116" => "ALIG",
818
+ "4113" => "ALLE",
819
+ "4114" => "ALLA",
820
+ "011(" => "OLIC",
821
+ "P115" => "PLIS",
822
+ "0117" => "OLIT",
823
+ "0115" => "OLIS",
824
+ "W110" => "WILO",
825
+ "011F" => "OLIF",
826
+ "F113" => "FILE",
827
+ "V113" => "VILE",
828
+ "011U" => "OLLU",
829
+ "P110" => "PILO",
830
+ "P111" => "PILL",
831
+ "H110" => "HILO",
832
+ "R114" => "RILA",
833
+ "711N" => "TLIN",
834
+ "8116" => "BLIG",
835
+ "6116" => "GLIG",
836
+ "5113" => "SILE",
837
+ "3114" => "ELLA",
838
+ "M111" => "MILL",
839
+ "M11K" => "MILK",
840
+ "M113" => "MILE",
841
+ "M11D" => "MILD",
842
+ "H113" => "HILE",
843
+ "611N" => "GLIN",
844
+ "411(" => "ALIC",
845
+ "4118" => "ALIB",
846
+ "K11Y" => "KILY",
847
+ "N113" => "NILE",
848
+ "011Y" => "OLLY",
849
+ "311Y" => "ELLY",
850
+ "411D" => "ALID",
851
+ "111U" => "ILLU",
852
+ "1110" => "ILIO",
853
+ "111N" => "ILLN",
854
+ "1113" => "ILLE",
855
+ "H114" => "HILA",
856
+ "H116" => "HLIG",
857
+ "711Y" => "TILY",
858
+ "U117" => "ULIT",
859
+ "7113" => "TILE",
860
+ "6113" => "GLIE",
861
+ "0110" => "OLLO",
862
+ "F11P" => "FLIP",
863
+ "F117" => "FILT",
864
+ "F11M" => "FILM",
865
+ "311N" => "ELIN",
866
+ "411U" => "ALLU",
867
+ "V115" => "VILS",
868
+ "N116" => "NLIG",
869
+ "3117" => "ELIT",
870
+ "R111" => "RILL",
871
+ "H111" => "HILL",
872
+ "M114" => "MILA",
873
+ "511K" => "SLIK",
874
+ "D113" => "DLIE",
875
+ "311M" => "ELIM",
876
+ "3116" => "ELIG",
877
+ "311(" => "ELIC",
878
+ "D11N" => "DLIN",
879
+ "Y116" => "YLIG",
880
+ "P11" => "PIL",
881
+ "11X" => "LIX",
882
+ "113" => "LIE",
883
+ "R11" => "RIL",
884
+ "11Y" => "ILY",
885
+ "H11" => "HIL",
886
+ "M11" => "MIL",
887
+ "112" => "LIZ",
888
+ "(11" => "CIL",
889
+ "11H" => "ILH",
890
+ "U11" => "ULI",
891
+ "K11" => "KIL",
892
+ "N11" => "NIL",
893
+ "W11" => "WII",
894
+ "Y11" => "YLL",
895
+ "611" => "GIL",
896
+ "X11" => "XIL",
897
+ "511" => "SIL",
898
+ "311" => "ELL",
899
+ "011" => "OLL",
900
+ "11U" => "LLU",
901
+ "11R" => "LIR",
902
+ "V11" => "VIL",
903
+ "711" => "TIL",
904
+ "D11" => "DII",
905
+ "11V" => "LIV",
906
+ "117" => "LIT",
907
+ "115" => "LIS",
908
+ "11Q" => "LIQ",
909
+ "11P" => "LIP",
910
+ "110" => "LIO",
911
+ "11N" => "LIN",
912
+ "11M" => "LIM",
913
+ "11K" => "LIK",
914
+ "116" => "LIG",
915
+ "11F" => "LIF",
916
+ "11D" => "LID",
917
+ "11(" => "LIC",
918
+ "118" => "LIB",
919
+ "114" => "LIA",
920
+ "F11" => "FIL",
921
+ "411" => "ALL",
922
+ "811" => "BIL",
923
+ "111" => "ILL",
924
+ "211" => "ZIL",
925
+ "11W" => "ILW",
926
+ "11" => "IL"
927
+ }.freeze
928
+ end
929
+ end
930
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Passweird
4
+ module Leet
5
+ # The Translate class is responsible for converting a given string
6
+ # into leet speak (1337 5p34k) and converting it back to normal text.
7
+ #
8
+ # Example usage:
9
+ # translator = Passweird::Leet::Translate.new("example")
10
+ # leet_string = translator.leet
11
+ # # => "3x4mpl3"
12
+ # normal_string = translator.unleet
13
+ # # => "example"
14
+ class Translate
15
+ attr_reader :given_string
16
+
17
+ CIPHER = {
18
+ "4" => "A",
19
+ "8" => "B",
20
+ "{" => "C",
21
+ "(" => "C",
22
+ "3" => "E",
23
+ "6" => "G",
24
+ "0" => "O",
25
+ "5" => "S",
26
+ "7" => "T",
27
+ "2" => "Z"
28
+ }.freeze
29
+
30
+ # Pattern to check if string is either:
31
+ # - Letters + Numbers
32
+ # - Letters + Special Characters
33
+ # - Letters + Numbers + Special Characters
34
+ MIXED_CHAR_REGEX = /^(?=.*[a-zA-Z])(?=.*[\d\W]).+$/.freeze
35
+
36
+ def self.leet(given_string)
37
+ new(given_string).leet
38
+ end
39
+
40
+ def self.leet?(given_string)
41
+ new(given_string).leet?
42
+ end
43
+
44
+ def self.leet_all(array_of_strings)
45
+ raise ArgumentError, "array_of_strings must be an Array" unless array_of_strings.is_a?(Array)
46
+
47
+ array_of_strings.map { |string| leet(string) }
48
+ end
49
+
50
+ def self.unleet(given_string)
51
+ new(given_string).unleet
52
+ end
53
+
54
+ def self.unleet_all(array_of_strings)
55
+ raise ArgumentError, "array_of_strings must be an Array" unless array_of_strings.is_a?(Array)
56
+
57
+ array_of_strings.map { |string| unleet(string) }
58
+ end
59
+
60
+ def initialize(given_string)
61
+ raise ArgumentError, "given_string must be a String" unless given_string.is_a?(String)
62
+
63
+ @given_string = given_string
64
+ end
65
+
66
+ # Converts the given_string to leet speak
67
+ #
68
+ # @return [String] the converted leet speak string
69
+ def leet
70
+ given_string.upcase.gsub(inverted_cipher_regex, inverted_cipher)
71
+ end
72
+
73
+ def leet?
74
+ mixed_characters?(given_string) && given_string != leet
75
+ end
76
+
77
+ # Converts the leet speak string back to normal text
78
+ #
79
+ # @return [String] the converted normal text string
80
+ def unleet
81
+ given_string.upcase.gsub(cipher_regex, cipher)
82
+ end
83
+
84
+ def cipher
85
+ @cipher ||= ExtendedCipher::CIPHER.merge(CIPHER)
86
+ end
87
+
88
+ def inverted_cipher
89
+ @inverted_cipher ||= cipher.invert
90
+ end
91
+
92
+ def cipher_regex
93
+ @cipher_regex ||= Regexp.union(cipher.keys)
94
+ end
95
+
96
+ def inverted_cipher_regex
97
+ @inverted_cipher_regex ||= Regexp.union(inverted_cipher.keys)
98
+ end
99
+
100
+ private
101
+
102
+ def mixed_characters?(string)
103
+ !string.match(MIXED_CHAR_REGEX).nil?
104
+ end
105
+ end
106
+ end
107
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Passweird
4
- VERSION = "0.2.1"
4
+ VERSION = "1.0.0"
5
5
  end
data/lib/passweird.rb CHANGED
@@ -4,9 +4,9 @@ require_relative "passweird/version"
4
4
  require_relative "passweird/blacklisted_term"
5
5
  require_relative "passweird/checker"
6
6
  require_relative "passweird/substringer"
7
- require_relative "passweird/leet_speak"
7
+ require_relative "passweird/leet/extended_cipher"
8
+ require_relative "passweird/leet/translate"
8
9
 
9
10
  module Passweird
10
11
  class Error < StandardError; end
11
- # Your code goes here...
12
12
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passweird
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rupert Señga
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-01-24 00:00:00.000000000 Z
11
+ date: 2025-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -49,7 +49,8 @@ files:
49
49
  - lib/passweird.rb
50
50
  - lib/passweird/blacklisted_term.rb
51
51
  - lib/passweird/checker.rb
52
- - lib/passweird/leet_speak.rb
52
+ - lib/passweird/leet/extended_cipher.rb
53
+ - lib/passweird/leet/translate.rb
53
54
  - lib/passweird/substringer.rb
54
55
  - lib/passweird/version.rb
55
56
  - passweird.gemspec
@@ -1,123 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Passweird
4
- # The LeetSpeak class is responsible for converting a given string
5
- # into leet speak (1337 5p34k) and converting it back to normal text.
6
- #
7
- # Example usage:
8
- # leet_speak = Passweird::LeetSpeak.new("example")
9
- # leet_string = leet_speak.leet
10
- # # => "3x4mpl3"
11
- # normal_string = leet_speak.unleet
12
- # # => "example"
13
- class LeetSpeak
14
- attr_reader :given_string
15
-
16
- ALPHABET_TO_SIMPLE_LEET = {
17
- # Uppercase
18
- "A" => "4",
19
- "B" => "8",
20
- "C" => "(",
21
- "E" => "3",
22
- "F" => "ƒ",
23
- "G" => "6",
24
- "H" => "#",
25
- "I" => "1",
26
- "N" => "И",
27
- "O" => "0",
28
- "R" => "Я",
29
- "S" => "5",
30
- "T" => "7",
31
- "U" => "U",
32
- "Y" => "¥",
33
- "Z" => "2",
34
- # Downcase
35
- "a" => "4",
36
- "b" => "8",
37
- "c" => "(",
38
- "e" => "3",
39
- "f" => "ƒ",
40
- "g" => "6",
41
- "h" => "#",
42
- "i" => "1",
43
- "n" => "и",
44
- "o" => "0",
45
- "r" => "я",
46
- "s" => "5",
47
- "t" => "7",
48
- "u" => "u",
49
- "y" => "¥",
50
- "z" => "2"
51
- }.freeze
52
-
53
- # Reference: https://en.wikipedia.org/wiki/Leet#Table_of_leet-speak_substitutes_for_normal_letters
54
- # Excluded leet speak equivalents that has 3 or more characters
55
- LEET_TO_ALPHABET = {
56
- "4" => "a", "@" => "a", "Д" => "a",
57
- "8" => "b", "ß" => "b",
58
- "(" => "c", "{" => "c",
59
- "3" => "e", "£" => "e", "€" => "e",
60
- "ƒ" => "f",
61
- "6" => "g", "9" => "g",
62
- "#" => "h",
63
- "1" => "i", "!" => "i",
64
- "И" => "n", "ท" => "n",
65
- "0" => "o", "Ø" => "o",
66
- "Я" => "r",
67
- "5" => "s", "$" => "s",
68
- "7" => "t",
69
- "พ" => "w", "₩" => "w", "ω" => "w",
70
- "¥" => "y",
71
- "2" => "z"
72
- }.freeze
73
-
74
-
75
- def self.leet(given_string)
76
- new(given_string).leet
77
- end
78
-
79
- def self.leet?(given_string)
80
- new(given_string).leet?
81
- end
82
-
83
- def self.leet_all(array_of_strings)
84
- raise ArgumentError, "array_of_strings must be an Array" unless array_of_strings.is_a?(Array)
85
-
86
- array_of_strings.map { |string| leet(string) }
87
- end
88
-
89
- def self.unleet(given_string)
90
- new(given_string).unleet
91
- end
92
-
93
- def self.unleet_all(array_of_strings)
94
- raise ArgumentError, "array_of_strings must be an Array" unless array_of_strings.is_a?(Array)
95
-
96
- array_of_strings.map { |string| unleet(string) }
97
- end
98
-
99
- def initialize(given_string)
100
- raise ArgumentError, "given_string must be a String" unless given_string.is_a?(String)
101
-
102
- @given_string = given_string
103
- end
104
-
105
- # Converts the given_string to leet speak
106
- #
107
- # @return [String] the converted leet speak string
108
- def leet
109
- given_string.gsub(/[#{ALPHABET_TO_SIMPLE_LEET.keys.join}]/, ALPHABET_TO_SIMPLE_LEET)
110
- end
111
-
112
- def leet?
113
- given_string != leet
114
- end
115
-
116
- # Converts the leet speak string back to normal text
117
- #
118
- # @return [String] the converted normal text string
119
- def unleet
120
- given_string.gsub(/[#{LEET_TO_ALPHABET.keys.join}]/, LEET_TO_ALPHABET)
121
- end
122
- end
123
- end