创建凯撒密码方法



所以我需要在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命名事物的方式。

但是现在让我们看一下源代码本身:

  1. 比较c >= $A & (c <= $Z)c isLetter
  2. 下一个字符的条件计算意味着我们想通过向右移动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:只创建一个实例,即方法返回的实例。

最新更新