I'm trying to make a caesar cipher in Swift Playgrounds but whenever the letter is for example "W" and I'm trying to shift it by 4, instead of getting "A" I just get an error. If the ascii code + shift doesn't exceed the ascii code for Z, it works just fine, otherwise I get
error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
Here is my code:
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)
}
Can anyone tell me why I get error when the ascii code for the letter + shift exceeds the "z"'s ascii code?
The shift
is UInt32
. So, with var modifiedShift = shift
, modifiedShift
is inferred to be UInt32
, too. So when you set modifiedShift
to 4, and then try to subtract 26 from it, that's not an acceptable UInt32
value.
Bottom line, use signed integers.
The problem is that the value of modifiedShift
can be negative which is NOT allowed for a value of type UInt32
so I would suggest to use only Int
whenever you can:
// 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)
}
Note: you can also use if case
for range matching. The following lines are semantically equivalent:
if unicode > 64 && unicode < 123 { ... }
if case 65..<123 = unicode { ... }
if (65..<123).contains(unicode) { ... }
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.