passweird 0.2.0 → 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: 8a90a6f24240691ccdd65ca1185eeda32e95dfc65302d1eb4fa118a5b8e45504
4
- data.tar.gz: 463bf49ad884574607e5682bd00de52008fca4ee272e9a49f4723c846d306d1c
3
+ metadata.gz: 3371f14ef5f297596e1afdf26d839efbd8f33cc35d59e9839148cf855253abbf
4
+ data.tar.gz: eba853d58d7a7809847cd0f73255fe3840dff4824c44f5bb354c9f0d523e09ba
5
5
  SHA512:
6
- metadata.gz: 940795845301e0ca6c127c168b70b7731fbfba2c779a95bfacf56bdb830e3d1cedfbc79d95e846da41d558f763e7478402450c5fde7c5e24c524af6ef657d201
7
- data.tar.gz: e20d91623ec83339f47f662f83787af532146c77964f67aa59f52c9ff584ef0d49ca825f33f588d870b803fb90ac17d6b65e0ed1b0d6ece93ffbcb8563289300
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.0)
4
+ passweird (1.0.0)
5
5
  activerecord (>= 7.0, < 8.0)
6
6
 
7
7
  GEM
@@ -38,33 +38,17 @@ module Passweird
38
38
  #
39
39
  # @return [Array<String>] an array of unique possible terms
40
40
  def possible_terms
41
- @possible_terms ||= all_substring_case_permutations.uniq
41
+ @possible_terms ||= (substrings + unleeted_substrings).map(&:downcase).uniq
42
42
  end
43
43
 
44
44
  private
45
45
 
46
- def all_substring_case_permutations
47
- @all_substring_case_permutations ||= substrings + unleeted_substrings + downcased_substrings + upcased_substrings
48
- end
49
-
50
- def all_substrings
51
- @all_substrings ||= (substrings + unleeted_substrings).uniq
52
- end
53
-
54
- def unleeted_substrings
55
- @unleeted_substrings ||= LeetSpeak.unleet_all(substrings)
56
- end
57
-
58
46
  def substrings
59
47
  @substrings ||= Substringer.substrings(password)
60
48
  end
61
49
 
62
- def downcased_substrings
63
- @downcased_substrings ||= all_substrings.map(&:downcase)
64
- end
65
-
66
- def upcased_substrings
67
- @upcased_substrings ||= all_substrings.map(&:upcase)
50
+ def unleeted_substrings
51
+ @unleeted_substrings ||= Leet::Translate.unleet_all(substrings)
68
52
  end
69
53
  end
70
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.0"
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.0
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.upcase.gsub(/[#{LEET_TO_ALPHABET.keys.join}]/, LEET_TO_ALPHABET)
121
- end
122
- end
123
- end