Why does Swift's Int operator error on this hexadecimal string?

I have this function to convert hex strings to base 64 strings in Swift. It works on small hexadecimal strings but not large ones?

// Convert a hexadecimal string representation to a base 64 string representation
func convertHexToB64(from hexadecimal: String) throws -> String {
    let strippedHexadecimal = hexadecimal.starts(with: "0x") ? String(hexadecimal[hexadecimal.index(hexadecimal.startIndex, offsetBy: 2)...]) : hexadecimal
    // With or without the following line, the code does not work
    let capitalized = strippedHexadecimal.uppercased() 
    if let integer = Int(capitalized, radix: 16) {
        let decimalString = String(integer)
        let encoded = decimalString.data(using: .utf8)?.base64EncodedString()
        if let result = encoded {
            return result
        }
    }
    throw Errors.runtimeError("Invalid hexadecimal integer.")
}

This:

print(try convertHexToB64(from: "0xA1"))

works, but this

print(try convertHexToB64(from: "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"))

errors.

The crash is because long hex input will overflow when attempting to initialise an Int from it. The maximum for a signed 64-bit integer (Int) is 0x7fffffffffffffff.

To fix this issue, you will want to convert the hex string to Data (or an array of bytes), and then base64 encode that data using the base64EncodedString() method that you are already using.

Here's a great answer on stack exchange that provides a few implementations for converting hex strings to Data (quite efficiently too): swift - Hex String to Bytes (NSData) - Code Review Stack Exchange

1 Like

Gotcha, thank you!

1 Like