UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

How to calculate the ROT13 of a string

Swift version: 5.6

Paul Hudson    @twostraws   

ROT13 is a simple algorithm that shifts letters in a string forward 13 places. It’s obviously not suitable for any serious encryption, but it’s very useful for hiding text so its meaning is not obvious – posting spoilers on a forum, for example, is best done using ROT13 to avoid someone getting annoyed.

It’s not hard to write a rot13() function, but it is a little harder to wrap it up neatly so you avoid global variables while still making it easy to use. Because you can’t add stored variables to an extension on String, the cleanest thing to do is create a new ROT13 type that can store the transformation from regular letters to ROT13, then run the calculation.

In code, it looks like this:

struct ROT13 {
    // create a dictionary that will store our character mapping
    private static var key = [Character: Character]()

    // create arrays of all uppercase and lowercase letters
    private static let uppercase = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    private static let lowercase = Array("abcdefghijklmnopqrstuvwxyz")

    static func string(_ string: String) -> String {
        // if this is the first time the method is being called, calculate the ROT13 key dictionary
        if ROT13.key.isEmpty {
            for i in 0 ..< 26 {
                ROT13.key[ROT13.uppercase[i]] = ROT13.uppercase[(i + 13) % 26]
                ROT13.key[ROT13.lowercase[i]] = ROT13.lowercase[(i + 13) % 26]
            }
        }

        // now return the transformed string
        let transformed = string.map { ROT13.key[$0] ?? $0 }
        return String(transformed)
    }
}

I’ve used private properties there because there’s no reason these implementation details should leak out, and it’s all static because there’s no need to create new ROT13 instances every time we need to run the conversion.

With that in place we can write an extension on String to calculate the ROT13 using our struct:

extension String {
    func rot13() -> String {
        return ROT13.string(self)
    }
}

That extension can now be called on a regular string, so users don’t need to care about how we implemented ROT13:

print("Hello, world!".rot13())
Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Available from iOS

Similar solutions…

About the Swift Knowledge Base

This is part of the Swift Knowledge Base, a free, searchable collection of solutions for common iOS questions.

BUY OUR BOOKS
Buy Pro Swift Buy Pro SwiftUI Buy Swift Design Patterns Buy Testing Swift Buy Hacking with iOS Buy Swift Coding Challenges Buy Swift on Sundays Volume One Buy Server-Side Swift Buy Advanced iOS Volume One Buy Advanced iOS Volume Two Buy Advanced iOS Volume Three Buy Hacking with watchOS Buy Hacking with tvOS Buy Hacking with macOS Buy Dive Into SpriteKit Buy Swift in Sixty Seconds Buy Objective-C for Swift Developers Buy Beyond Code

Was this page useful? Let us know!

Average rating: 3.0/5

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.