4

I'm trying to convert an hex string to text.

This is what i have:

// Str to Hex
func strToHex(text: String) -> String {
    let hexString = text.data(using: .utf8)!.map{ String(format:"%02x", $0) }.joined()

   return "0x" + hexString

}

and I'm trying to reverse the hex string that I've just created back to the original one.

So, for example:

let foo: String = strToHex(text: "K8") //output: "0x4b38"

and i would like to do something like

let bar: String = hexToStr(hex: "0x4b38") //output: "K8"

can someone help me? Thank you

Hamish
  • 78,605
  • 19
  • 187
  • 280
nsollazzo
  • 43
  • 1
  • 5
  • Here is a method to create Data from a hex string: http://stackoverflow.com/a/40278391/1187415, then use `String(data:, encoding:)` – Martin R Mar 12 '17 at 21:23
  • Perhaps this is what you are looking for http://stackoverflow.com/questions/31816182/how-to-parse-a-string-of-hex-into-ascii-equivalent-in-swift-2 ? – Martin R Mar 14 '17 at 15:35

3 Answers3

10

You probably can use something like this:

func hexToStr(text: String) -> String {

    let regex = try! NSRegularExpression(pattern: "(0x)?([0-9A-Fa-f]{2})", options: .caseInsensitive)
    let textNS = text as NSString
    let matchesArray = regex.matches(in: textNS as String, options: [], range: NSMakeRange(0, textNS.length))
    let characters = matchesArray.map {
        Character(UnicodeScalar(UInt32(textNS.substring(with: $0.rangeAt(2)), radix: 16)!)!)
    }

    return String(characters)
}
Alexandre Lara
  • 2,464
  • 1
  • 28
  • 35
0

NSRegularExpression is overkill for the job. You can convert the string to byte array by grabbing two characters at a time:

func hexToString(hex: String) -> String? {
    guard hex.characters.count % 2 == 0 else {
        return nil
    }

    var bytes = [CChar]()

    var startIndex = hex.index(hex.startIndex, offsetBy: 2)
    while startIndex < hex.endIndex {
        let endIndex = hex.index(startIndex, offsetBy: 2)
        let substr = hex[startIndex..<endIndex]

        if let byte = Int8(substr, radix: 16) {
            bytes.append(byte)
        } else {
            return nil
        }

        startIndex = endIndex
    }

    bytes.append(0)     
    return String(cString: bytes)
}
Code Different
  • 90,614
  • 16
  • 144
  • 163
  • 1
    `String(cString:)` expects a *null-terminated* UTF-8 data. Your array is not null-terminated which causes undefined behaviour. In addition, this does not work with non-ASCII characters. – Martin R Mar 13 '17 at 09:20
0

Solution that supports also special chars like emojis etc.

static func hexToPlain(input: String) -> String {
    let pairs = toPairsOfChars(pairs: [], string: input)
    let bytes = pairs.map { UInt8($0, radix: 16)! }
    let data = Data(bytes)
    return String(bytes: data, encoding: .utf8)!
}
tomysek
  • 159
  • 1
  • 10