Swift4 Playgrounds凯撒密码错误

Swift4 Playgrounds Caesar Cipher error

我正在尝试在 Swift Playgrounds 中使用凯撒密码,但是每当字母是 "W" 并且我试图将它移动 4,而不是得到 "A" 我只是得到一个错误。如果 ascii 码 + shift 不超过 Z 的 ascii 码,它工作正常,否则我得到

error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).

这是我的代码:

func cipher(messageToCipher: String, shift: UInt32) {
    var ciphredMessage = ""

    for char in messageToCipher.unicodeScalars {
        var unicode : UInt32 = char.value

        if char.value > 64 && char.value < 123 {
            var modifiedShift = shift
            if char.value >= 65 && char.value <= 90 {
                while char.value + modifiedShift > 90 {
                 //return to A
                    modifiedShift -= 26
                }
            } else if char.value >= 97 && char.value <= 122 {
                while char.value + modifiedShift > 122 {
                  //return to a
                    modifiedShift -= 26
                }
            }

            unicode = char.value + modifiedShift
        }

        ciphredMessage += String(UnicodeScalar(unicode)!)
    }

    print(ciphredMessage)
}

谁能告诉我为什么当字母 + shift 的 ascii 码超过 "z" 的 ascii 码时出现错误?

shiftUInt32。因此,对于 var modifiedShift = shiftmodifiedShift 也被推断为 UInt32。因此,当您将 modifiedShift 设置为 4,然后尝试从中减去 26 时,这不是可接受的 UInt32 值。

底线,使用有符号整数。

问题是 modifiedShift 的值可以为负值,这对于 UInt32 类型的值是不允许的,所以我建议只要可以就只使用 Int

// use `Int` for `shift`
func cipher(messageToCipher: String, shift: Int) {
    var ciphredMessage = ""

    for char in messageToCipher.unicodeScalars {
        // convert to `Int`
        var unicode = Int(char.value)

        if unicode > 64 && unicode < 123 {
            var modifiedShift = shift
            if unicode >= 65 && unicode <= 90 {
                while unicode + modifiedShift > 90 {
                    //return to A
                    modifiedShift -= 26
                }
            } else if unicode >= 97 && unicode <= 122 {
                while unicode + modifiedShift > 122 {
                    //return to a
                    modifiedShift -= 26
                }
            }

            unicode += modifiedShift
        }

        ciphredMessage += String(UnicodeScalar(unicode)!)
    }

    print(ciphredMessage)
}

注意:您也可以使用if case进行范围匹配。以下几行在语义上是等价的:

if unicode > 64 && unicode < 123 { ... }
if case 65..<123 = unicode { ... }
if (65..<123).contains(unicode) { ... }