1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133 | #!/home/olus2000/programy/smalltalk-3.2/gst
Object subclass: CipherCracker [
| corpusBag inputBag count tbl |
<comment: 'I crack subtitution ciphers ^_^'>
CipherCracker class >> new [
| r |
r := super new.
r init.
^r
]
init [
<category: 'initialization'>
corpusBag := Bag new.
inputBag := Bag new.
count := 0.
]
learn: corpus [
<category: 'processing'>
<comment: 'I update the cracker to expect text similar to the one provided.'>
corpus do: [:c | c isLetter ifTrue: [corpusBag add: c asLowercase]].
]
prescan: input [
<category: 'processing'>
<comment: 'I learn the frequency of letters in the input.'>
input do: [:c | c isLetter ifTrue: [inputBag add: c asLowercase]].
]
beforeCrack [
<category: 'processing'>
tbl := LookupTable new.
inputBag sortedByCount
with: corpusBag sortedByCount
do: [:i :c | tbl at: i value put: c value].
]
crack: string [
<category: 'processing'>
<comment: 'I cracka da string.'>
count := count + 1.
^(string collect: [:c | c isUppercase
ifTrue: [(tbl at: c asLowercase ifAbsent: [c asLowercase]) asUppercase]
ifFalse: [tbl at: c ifAbsent: [c]]
]) asString
]
stats [
<category: 'statistics'>
^'BORN TO SPAM
WORLD IS A MJAU
鬼神 Love Em All %1
I am louna ^_^
' % { count }
]
]
Dictionary extend [
at: key ifAbsent: absent ifPresent: present [
present value: (self at: key ifAbsent: [^absent value])
]
]
FileStream class extend [
withOpen: fn mode: m do: block [
| f |
f := self open: fn mode: m.
[block value: f] ensure: [f close].
]
withOpen: fn1 mode: m1 and: fn2 mode: m2 do: block [
| f1 f2 |
f1 := self open: fn1 mode: m1.
f2 := self open: fn2 mode: m2.
[block value: f1 value: f2] ensure: [f1 close. f2 close].
]
]
Object subclass: Program [
| input output corpus |
arguments := LookupTable new
at: $c put: #corpus:;
at: $i put: #input:;
at: $o put: #output:;
yourself.
corpus: filename [corpus := filename]
input: filename [input := filename]
output: filename [output := filename]
run [
| err cracker |
err := false.
Smalltalk arguments: '-c: -i: -o:'
do: [:name :arg | arguments
at: name
ifAbsent: [err := true]
ifPresent: [:sel | self perform: sel with: arg].
]
ifError: [^self usage].
err ifTrue: [^self usage].
corpus ifNil: [^self usage].
input ifNil: [^self usage].
output ifNil: [^self usage].
cracker := CipherCracker new.
FileStream withOpen: corpus
mode: FileStream read
do: [:f | f linesDo: [:l | cracker learn: l]].
FileStream withOpen: input
mode: FileStream read
and: output
mode: FileStream write
do: [:in :out |
in linesDo: [:line | cracker prescan: line].
cracker beforeCrack.
in reset.
in linesDo: [:line | out << (cracker crack: line); nl]
].
cracker stats displayNl.
]
usage [
FileStream stderr << 'cracker.st -c CORPUS -i INPUT -o OUTPUT'; nl.
ObjectMemory quit: 2
]
]
Program new run
|
post a comment