Browse Source

implement cracking

Scitoshi Nakayobro 1 year ago
parent
commit
089f60648e
5 changed files with 61 additions and 26 deletions
  1. 7
    7
      src/analyze.lisp
  2. 10
    10
      src/caesar.lisp
  3. 9
    6
      src/constants.lisp
  4. 31
    0
      src/crack.lisp
  5. 4
    3
      src/main.lisp

+ 7
- 7
src/analyze.lisp View File

@@ -1,15 +1,15 @@
1 1
 (import core/base (get-idx set-idx!))
2 2
 (import core/string (string->bytes))
3 3
 
4
-(import constants (CAPITAL_A_ASCII CAPITAL_Z_ASCII LOWER_A_ASCII LOWER_Z_ASCII))
4
+(import constants (CAPITAL-A-ASCII CAPITAL-Z-ASCII LOWER-A-ASCII LOWER-Z-ASCII ALPHABET-LETTERS))
5 5
 
6
-(defun normalize (b)
6
+(defun letter-index (b)
7 7
 	:hidden
8 8
 	(cond
9
-		[(and (>= b CAPITAL_A_ASCII) (<= b CAPITAL_Z_ASCII))
10
-			(- b CAPITAL_A_ASCII)]
11
-		[(and (>= b LOWER_A_ASCII) (<= b LOWER_Z_ASCII))
12
-			(- b LOWER_A_ASCII)]
9
+		[(and (>= b CAPITAL-A-ASCII) (<= b CAPITAL-Z-ASCII))
10
+			(- b CAPITAL-A-ASCII)]
11
+		[(and (>= b LOWER-A-ASCII) (<= b LOWER-Z-ASCII))
12
+			(- b LOWER-A-ASCII)]
13 13
 		[else
14 14
 			nil]))
15 15
 
@@ -18,7 +18,7 @@
18 18
 		   (total 0)
19 19
 		   (data (string->bytes text))]
20 20
 		(for-each b data
21
-			(when-with (c (normalize b))
21
+			(when-with (c (letter-index b))
22 22
 				(inc! c)
23 23
 				(set-idx! frequencies c (+ (get-idx frequencies c) 1))
24 24
 				(inc! total)))

+ 10
- 10
src/caesar.lisp View File

@@ -1,15 +1,15 @@
1 1
 (import core/string (string->bytes bytes->string))
2 2
 
3
-(import constants (ALPHABET_LETTERS CAPITAL_A_ASCII CAPITAL_Z_ASCII LOWER_A_ASCII LOWER_Z_ASCII))
3
+(import constants (ALPHABET-LETTERS CAPITAL-A-ASCII CAPITAL-Z-ASCII LOWER-A-ASCII LOWER-Z-ASCII))
4 4
 
5
-(defun do-shift (c shift _min _max)
5
+(defun do-shift (c shift -min -max)
6 6
 	:hidden
7 7
 	(with (n (+ c shift))
8 8
 		(cond
9
-			[(< n _min)
10
-				(+ n ALPHABET_LETTERS)]
11
-			[(> n _max)
12
-				(- n ALPHABET_LETTERS)]
9
+			[(< n -min)
10
+				(+ n ALPHABET-LETTERS)]
11
+			[(> n -max)
12
+				(- n ALPHABET-LETTERS)]
13 13
 			[else
14 14
 				n])))
15 15
 
@@ -18,10 +18,10 @@
18 18
 		   (transformed '())]
19 19
 		(for-each c original
20 20
 			(cond
21
-				[(and (>= c CAPITAL_A_ASCII) (<= c CAPITAL_Z_ASCII))
22
-					(push! transformed (do-shift c shift CAPITAL_A_ASCII CAPITAL_Z_ASCII))]
23
-				[(and (>= c LOWER_A_ASCII) (<= c LOWER_Z_ASCII))
24
-					(push! transformed (do-shift c shift LOWER_A_ASCII LOWER_Z_ASCII))]
21
+				[(and (>= c CAPITAL-A-ASCII) (<= c CAPITAL-Z-ASCII))
22
+					(push! transformed (do-shift c shift CAPITAL-A-ASCII CAPITAL-Z-ASCII))]
23
+				[(and (>= c LOWER-A-ASCII) (<= c LOWER-Z-ASCII))
24
+					(push! transformed (do-shift c shift LOWER-A-ASCII LOWER-Z-ASCII))]
25 25
 				[else
26 26
 					(push! transformed c)]))
27 27
 		(bytes->string transformed)))

+ 9
- 6
src/constants.lisp View File

@@ -1,7 +1,10 @@
1
-(define ALPHABET_LETTERS 	26)
2
-(define CAPITAL_A_ASCII 	65)
3
-(define CAPITAL_Z_ASCII 	90)
4
-(define LOWER_A_ASCII 		97)
5
-(define LOWER_Z_ASCII 		122)
1
+(define ALPHABET-LETTERS 	26)
6 2
 
7
-(define LETTERS 		 	'("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"))
3
+(define CAPITAL-A-ASCII 	65)
4
+(define CAPITAL-Z-ASCII 	90)
5
+(define LOWER-A-ASCII 		97)
6
+(define LOWER-Z-ASCII 		122)
7
+
8
+(define LETTERS 		 	'("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"))
9
+
10
+(define ENGLISH-LETTERS-RELATIVE-FREQUENCIES '(0.08167 0.01492 0.02782 0.04253 0.12702 0.02228 0.02015 0.06094 0.06966 0.00153 0.00772 0.04025 0.02406 0.06749 0.07507 0.01929 0.00095 0.05987 0.06327 0.09056 0.02758 0.00978 0.0236 0.0015 0.01974 0.00074))

+ 31
- 0
src/crack.lisp View File

@@ -0,0 +1,31 @@
1
+(import lua/math (sqrt huge))
2
+(import core/base (get-idx set-idx!))
3
+(import test/assert (assert!))
4
+
5
+(import constants (ALPHABET-LETTERS ENGLISH-LETTERS-RELATIVE-FREQUENCIES))
6
+
7
+(import caesar (transform))
8
+(import analyze (analyze))
9
+
10
+(defun distance (a b)
11
+	:hidden
12
+	(assert! (= (len# a) 26) "invalid frequency profile")
13
+	(assert! (= (len# b) 26) "invalid frequency profile")
14
+	(with (total 0)
15
+		(for i 1 ALPHABET-LETTERS 1
16
+			(let* [(d (- (get-idx b i) (get-idx a i)))
17
+				   (d2 (* d d))]
18
+				(set! total (+ total d2))))
19
+		(sqrt total)))
20
+
21
+(defun crack (ciphertext)
22
+	(let* [(best-distance huge)
23
+		   (best-shift nil)]
24
+		(for i 1 (- ALPHABET-LETTERS 1) 1
25
+			(let* [(maybe-cleartext (transform i ciphertext))
26
+				   (maybe-cleartext-freqs (analyze maybe-cleartext))
27
+				   (dist-from-best (distance ENGLISH-LETTERS-RELATIVE-FREQUENCIES maybe-cleartext-freqs))]
28
+				(when (< dist-from-best best-distance)
29
+					(set! best-distance dist-from-best)
30
+					(set! best-shift i))))
31
+		best-shift))

+ 4
- 3
src/main.lisp View File

@@ -1,8 +1,9 @@
1 1
 (import core/base (get-idx))
2 2
 (import io (read-all!))
3 3
 
4
-(import caesar)
4
+(import caesar (transform))
5 5
 (import analyze (analyze))
6
+(import crack (crack))
6 7
 (import constants (LETTERS))
7 8
 
8 9
 (defun usage! ()
@@ -24,7 +25,7 @@
24 25
 	(case mode
25 26
 		["transform"
26 27
 			(nargs-or-usage! 3)
27
-			(print! (caesar/transform (string->number (get-idx *arguments* 2)) data))]
28
+			(print! (transform (string->number (get-idx *arguments* 2)) data))]
28 29
 		["analyze"
29 30
 			(nargs-or-usage! 2)
30 31
 			(with (frequencies (analyze data))
@@ -35,7 +36,7 @@
35 36
 						(print! ($ "${c},${f}")))))]
36 37
 		["crack"
37 38
 			(nargs-or-usage! 2)
38
-			]
39
+			(print! (transform (crack data) data))]
39 40
 		[_
40 41
 			(print! ($ "Unrecognized mode '${mode}'"))
41 42
 			(usage!)]))

Loading…
Cancel
Save