2017-12-03 2 views
1

Swift Playgrounds에서 시저 암호를 만들려고 시도하고 있지만 "W"와 같은 문자가있을 때마다 "A"를 얻는 대신 4로 이동하려고합니다. 오류. 내가 할 이유Swift4 Playgrounds Caesar Cipher 오류

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) 
} 

사람이 말해 줄 수 : 아스키 코드 + 시프트 Z의 아스키 코드를 초과하지 않는 경우, 그렇지 않으면 내가 여기

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

내 코드입니다 얻을, 잘 작동 문자 + 시프트의 ASCII 코드가 "z"의 ASCII 코드를 초과하면 오류가 발생합니까?

답변

3

shiftUInt32입니다. 따라서 var modifiedShift = shift의 경우 도 UInt32으로 추정됩니다. 따라서 modifiedShift을 4로 설정하고 26을 빼면 그 값은 UInt32이 아닙니다.

결론은 부호있는 정수를 사용합니다.

+0

가 0보다 낮은 그렇지 않으면만큼이 조건이 예 – Qbyte

+0

을 성취 그것에서 뺄 수, 나는 삭제 내 내가 인터넷에서 UInt32의 범위를 확인하고 내가 바보라는 것을 깨닫고 나서 의견을 말하십시오. 고마워, UInt32 범위에 대해 잠깐 생각하지 않았다. – AndreiVataselu

1

문제는 그래서 당신은 할 수 있습니다 때마다에만 Int를 사용하는 것이 좋습니다 것입니다 modifiedShift의 값이 유형 UInt32의 값에 허용되지 않는 음수가 될 수 있다는 것입니다 :

// 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 다음 줄은 의미 적으로 동일하다 : 그것은 단지 될 수있는`UInt32` 값에 사용할 수 없습니다 @AndreiVataselu

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