简体   繁体   中英

Caesar cipher on Swift error with decrypt

I make an application for the report on the subject of system security. Caesar 's swift code. and I ran into a problem when in decrypting phase.

When I enter the key, the program randomly knocks out the error:

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Or an array exit error

I'm a newbie. Please explain to me how I can fix this error and make my program work properly.

Google didn't help me.

import UIKit

class CaesarCipher: UIViewController {
    @IBOutlet weak var messageText: UITextField!
    @IBOutlet weak var keyText: UITextField!
    @IBOutlet weak var cipherTextLabel: UILabel!

    ////////////////////////////////////////////////////////////////////////////

    @IBOutlet weak var cryptMessageText: UITextField!
    @IBOutlet weak var cryptKeyText: UITextField!
    @IBOutlet weak var decryptTextLabel: UILabel!

    @IBAction func cipherButton(_ sender: Any) {

        if (messageText.text == "") || (keyText.text == "")
        {
            let alert = UIAlertController(title: "Ошибка", message: "Одно, или несколько полей пустые", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Ок", style: .default, handler: nil))
            self.present(alert, animated: true)
        }
        else
        {
            let key = keyText.text
            let e: Int32 = Int32.init(key!)!
            //let upKey: Int32 = Int32.init(&e)

            let messageCipher = messageText.text
            // var i: Int8 = Int8.init(messageCipher!)!
            //let up: UnsafeMutablePointer<Int8> = UnsafeMutablePointer<Int8>.init(&i)

            //cipherTextLabel = encrypt(up, e)
            let encryptText = cipher(messageCipher!, shift: Int(e))
            cipherTextLabel.text = "\(encryptText)"
        } 
    }

    //////////////////////////////////////////////////////////////////////////////////////////////

    @IBAction func decryptButton(_ sender: Any) {

        if (cryptMessageText.text == "") || (cryptKeyText.text == "")
        {
            let alert = UIAlertController(title: "Ошибка", message: "Одно, или несколько полей пустые", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Ок", style: .default, handler: nil))
            self.present(alert, animated: true)
        }
        else
        {
            let cryptKey = cryptKeyText.text
            let e: Int = Int.init(cryptKey!)!
            //let upKey: Int32 = Int32.init(&e)

            let decryptMessageText = cryptMessageText.text
            // var i: Int8 = Int8.init(messageCipher!)!
            //let up: UnsafeMutablePointer<Int8> = UnsafeMutablePointer<Int8>.init(&i)

            //cipherTextLabel = encrypt(up, e)
            let decryptText = decipher(decryptMessageText!, shift2: Int(e))
            decryptTextLabel.text = "\(decryptText)"
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.hideKeyboard()
    }
}

func cipher( _ text:String, shift:Int ) -> String {

    var textCharArray:[Character] = Array( text.characters )

    let alphabet = Array("0123456789abcdefghijklmnopqrstuvxyzABCDEFGHIJKLMNOPQRSTUWVXYZ !".characters);

    let offset = alphabet.count // alphabet.length in other languages

    for i in 0 ..< text.characters.count {

        let oldChar = textCharArray[ i ]
        let oldCharIdx = alphabet.index( of:oldChar ) // get index of

        let oldCharIdxUnwrapped = oldCharIdx // oldCharIdx can be null!
        let newCharIdx = ( oldCharIdxUnwrapped! + shift + offset ) % offset

        let newChar = alphabet[ newCharIdx ]

        textCharArray[ i ] = newChar
    }

    return String( textCharArray )
}

func decipher( _ text:String, shift2:Int ) -> String {

    // when calling a function you don't have to specify the first argument...
    // For other arguments you have to specify it!
    return cipher( text, shift:shift2 * -1 )
}

The error you see usually gets thrown when there is an Optional (a value that could be nil) and you try to unwrap it (using '!').

Swift also introduces optional types, which handle the absence of a value. Optionals say either “there is a value, and it equals x” or “there isn't a value at all”.

That being said, the problem here is that UITextfields when "empty" might have nil for their text property. so when you do

    let key = keyText.text
    let e: Int32 = Int32.init(key!)!

key could be a nil value. And (nil)! will result in Unexpectedly found nil while unwrapping an Optional value .

To fix this, I suggest you add a nil check for your UITextfield's text property or change your if else block to the following

    if let key = keyText.text, let messageCipher = messageText.text, !key.isEmpty, !messageCipher.isEmpty {
        // key and messageCipher are neither nil nor empty.
    } else {
        // keyText.text or messageText.text are either nil or empty
    }

If you are interested in swift programming and making apps for iOS, I suggest you look up more on how swift deals with optional s, and implicitly unwrapped optionals. A place to start would be https://docs.swift.org/swift-book/LanguageGuide/TheBasics.html and follow up with tutorials.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM