创建凯撒密码方法

时间:2016-09-24 04:48:58

标签: smalltalk pharo caesar-cipher

所以我需要在smalltalk中获取Caesar Cipher代码并创建一个方法并使用它以便我可以对其进行以下测试

|aString|
aString:=Caesar new encrypt: 'CAESAR'.
Transcript show: aString.

我已经上课了。但我需要制定它的方法。

我找到了这个,但我怎么能用这个方法制作一个方法,所以我可以在游乐场中使用上述所有代码。

| 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.

所以为了清楚起见,我需要使用Caesar Cipher代码创建一个方法并使用&#34; aString&#34;开头的代码并用它进行测试。我上面有这个代码但是它已经包含了文本,并且不能放入方法中。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

正如Max在评论中所说,上面的代码可以放在一个方法中。唯一缺少的部分是选择器和形式参数的第一行:

caesarCipherOf: strText
  <insert the code here>

Max的另一个好建议是调用参数aString而不是strText,因为这更符合Smalltalkers如何命名。

但现在让我们来看看源代码本身:

  1. 比较c >= $A & (c <= $Z)表示c isLetter
  2. 下一个字符的条件计算意味着我们希望通过向右移动c个字符来移动3,如果它超出{{1},则将其包裹起来}。这可以很容易地表达为:

    $Z

    其中(c codePoint - 64 + 3 \\ 26 + 64) asCharacter 64 = $A codePoint - 1与任何给定大写字符$A之间的偏移量。另请注意,我已将c替换为asciiValue

  3. 通过这两个观察,该方法可以重写为

    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的结果。相反,#,只创建一个实例,即该方法返回的实例。