所以我需要在smalltalk中获得Caesar Cipher代码并创建一个方法并使用它,以便我可以对它进行以下测试
|aString|
aString:=Caesar new encrypt: 'CAESAR'.
Transcript show: aString.
我已经制作了这个类。但是我需要找到它的方法
我发现了这个,但是我怎么能从中创建一个方法,这样我就可以在playground中使用上面所有的代码。
| i c strCipherText strText iShiftValue iShift |
strText := 'the quick brown fox jumps over the lazy dog'.
iShiftValue := 3.
strCipherText := ''.
iShift := iShiftValue \ 26.
i := 1.
[ i <= (strText size) ]
whileTrue: [
c := (strText at: i) asUppercase.
( ( c >= $A) & ( c <= $Z ) )
ifTrue: [
((c asciiValue) + iShift > $Z asciiValue)
ifTrue: [
strCipherText := strCipherText, (((c asciiValue) + iShift - 26)
asCharacter asString).
]
ifFalse: [
strCipherText := strCipherText, (((c asciiValue) + iShift)
asCharacter asString).
].
]
ifFalse: [
strCipherText := strCipherText, ' '.
].
i := i + 1.
].
Transcript show: strCipherText.
Transcript cr.
所以为了说清楚,我需要使用凯撒密码创建一个方法,并在开始时使用"aString"代码并使用该代码进行测试。我有上面的代码,但它已经有了文本,不能放入方法。
任何帮助将不胜感激。
正如Max在他的评论中所说,上面的代码可以放在一个方法中。唯一缺少的部分是带有选择器和形式参数的第一行:
caesarCipherOf: strText
<insert the code here>
Max的另一个好建议是将参数命名为aString
而不是strText
,因为这更符合Smalltalkers命名事物的方式。
但是现在让我们看一下源代码本身:
- 比较
c >= $A & (c <= $Z)
为c isLetter
。 下一个字符的条件计算意味着我们想通过向右移动
3
字符来移位c
,如果超过$Z
,则将其环绕。这可以很容易地表示为:(c codePoint - 64 + 3 \ 26 + 64) asCharacter
,其中
64 = $A codePoint - 1
是$A
和任何给定的大写字符c
之间的偏移量。还请注意,我已将asciiValue
替换为codePoint
。
有了这两个观察值,该方法可以重写为
caesarCipherOf: aString
^aString collect: [:c |
c isLetter
ifTrue: [(c asUppercase codePoint - 64 + 3 \ 26 + 64) asCharacter]
ifFalse: [$ ]]
这不仅更短,而且更有效,因为它避免了在每个字符处创建两个新的String
实例。具体来说,任何形式为
string := string , <character> asString
创建两个Strings
:一个是发送#asString
的结果,另一个是发送连接消息#,
的结果。相反,#collect:
只创建一个实例,即方法返回的实例。